react-native 0.83.4 → 0.83.6

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 (114) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +1 -1
  2. package/Libraries/Utilities/Appearance.js +6 -1
  3. package/Libraries/Utilities/HMRClient.js +28 -1
  4. package/React/Base/RCTVersion.m +1 -1
  5. package/React/CoreModules/RCTDevLoadingView.mm +17 -0
  6. package/React/DevSupport/RCTFrameTimingsObserver.h +24 -0
  7. package/React/DevSupport/RCTFrameTimingsObserver.mm +298 -0
  8. package/React/FBReactNativeSpec/FBReactNativeSpecJSI.h +16 -0
  9. package/ReactAndroid/api/ReactAndroid.api +0 -9
  10. package/ReactAndroid/gradle.properties +1 -1
  11. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgelessDevSupportManager.kt +2 -2
  12. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.kt +7 -7
  13. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/InspectorFlags.kt +4 -0
  14. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingSequence.kt +16 -0
  15. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt +275 -0
  16. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/TracingState.kt +17 -0
  17. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/TracingStateListener.kt +15 -0
  18. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/{interfaces → inspector}/TracingStateProvider.kt +1 -1
  19. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorInspectorTargetBinding.kt +1 -1
  20. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorOverlayManager.kt +4 -4
  21. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorOverlayView.kt +3 -3
  22. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/perfmonitor/PerfMonitorUpdateListener.kt +1 -1
  23. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +13 -1
  24. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +21 -1
  25. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +5 -1
  26. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +5 -1
  27. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +23 -1
  28. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +5 -1
  29. package/ReactAndroid/src/main/java/com/facebook/react/internal/tracing/PerformanceTracer.kt +39 -0
  30. package/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BlobModule.kt +1 -1
  31. package/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkEventUtil.kt +20 -19
  32. package/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.kt +6 -12
  33. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
  34. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +86 -4
  35. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImplDevHelper.kt +3 -3
  36. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostInspectorTarget.kt +10 -6
  37. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.cpp +22 -0
  38. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.h +2 -0
  39. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +29 -1
  40. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +7 -1
  41. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.cpp +196 -17
  42. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h +168 -18
  43. package/ReactAndroid/src/main/jni/third-party/folly/CMakeLists.txt +1 -0
  44. package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
  45. package/ReactCommon/hermes/inspector-modern/chrome/Registration.cpp +44 -2
  46. package/ReactCommon/jsinspector-modern/HostAgent.cpp +45 -10
  47. package/ReactCommon/jsinspector-modern/HostAgent.h +2 -2
  48. package/ReactCommon/jsinspector-modern/HostTarget.cpp +14 -7
  49. package/ReactCommon/jsinspector-modern/HostTarget.h +101 -14
  50. package/ReactCommon/jsinspector-modern/HostTargetTraceRecording.cpp +39 -8
  51. package/ReactCommon/jsinspector-modern/HostTargetTraceRecording.h +42 -5
  52. package/ReactCommon/jsinspector-modern/HostTargetTracing.cpp +54 -21
  53. package/ReactCommon/jsinspector-modern/HostTargetTracing.h +89 -0
  54. package/ReactCommon/jsinspector-modern/InspectorFlags.cpp +12 -0
  55. package/ReactCommon/jsinspector-modern/InspectorFlags.h +12 -0
  56. package/ReactCommon/jsinspector-modern/InspectorInterfaces.cpp +3 -7
  57. package/ReactCommon/jsinspector-modern/InstanceAgent.cpp +2 -11
  58. package/ReactCommon/jsinspector-modern/NetworkIOAgent.cpp +1 -1
  59. package/ReactCommon/jsinspector-modern/RuntimeAgent.cpp +19 -0
  60. package/ReactCommon/jsinspector-modern/RuntimeAgent.h +7 -0
  61. package/ReactCommon/jsinspector-modern/RuntimeTarget.cpp +33 -0
  62. package/ReactCommon/jsinspector-modern/RuntimeTarget.h +6 -0
  63. package/ReactCommon/jsinspector-modern/TracingAgent.cpp +29 -13
  64. package/ReactCommon/jsinspector-modern/TracingAgent.h +5 -4
  65. package/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp +65 -0
  66. package/ReactCommon/jsinspector-modern/tests/InspectorMocks.h +23 -2
  67. package/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp +1 -0
  68. package/ReactCommon/jsinspector-modern/tests/NetworkReporterTest.cpp +1 -0
  69. package/ReactCommon/jsinspector-modern/tests/TracingTest.cpp +335 -0
  70. package/ReactCommon/jsinspector-modern/tests/TracingTest.h +95 -0
  71. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.cpp +10 -0
  72. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h +3 -1
  73. package/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt +1 -0
  74. package/ReactCommon/jsinspector-modern/tracing/FrameTimingSequence.h +61 -0
  75. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfile.h +43 -0
  76. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.cpp +165 -0
  77. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.h +50 -0
  78. package/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.cpp +16 -14
  79. package/ReactCommon/jsinspector-modern/tracing/PerformanceTracerSection.h +113 -0
  80. package/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec +1 -0
  81. package/ReactCommon/jsinspector-modern/tracing/TimeWindowedBuffer.h +158 -0
  82. package/ReactCommon/jsinspector-modern/tracing/TraceEvent.h +2 -1
  83. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.cpp +100 -0
  84. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.h +60 -0
  85. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.cpp +44 -1
  86. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.h +7 -0
  87. package/ReactCommon/jsinspector-modern/tracing/TraceRecordingState.h +18 -7
  88. package/ReactCommon/jsinspector-modern/tracing/TracingCategory.h +136 -0
  89. package/ReactCommon/jsinspector-modern/tracing/tests/TimeWindowedBufferTest.cpp +352 -0
  90. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +9 -1
  91. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +11 -1
  92. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +65 -29
  93. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +6 -2
  94. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +9 -1
  95. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +19 -1
  96. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +3 -1
  97. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +3 -1
  98. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +11 -1
  99. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +5 -1
  100. package/ReactCommon/react/performance/timeline/PerformanceObserver.cpp +18 -6
  101. package/ReactCommon/react/performance/timeline/PerformanceObserver.h +2 -0
  102. package/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +115 -0
  103. package/ReactCommon/{jsinspector-modern → react/utils}/Base64.h +2 -2
  104. package/gradle/libs.versions.toml +1 -1
  105. package/package.json +10 -10
  106. package/scripts/cocoapods/utils.rb +1 -0
  107. package/src/private/featureflags/ReactNativeFeatureFlags.js +11 -1
  108. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +3 -1
  109. package/third-party-podspecs/RCT-Folly.podspec +1 -1
  110. package/third-party-podspecs/fmt.podspec +2 -2
  111. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/TracingState.kt +0 -19
  112. package/ReactCommon/jsinspector-modern/tracing/TraceRecordingStateSerializer.cpp +0 -68
  113. package/ReactCommon/jsinspector-modern/tracing/TraceRecordingStateSerializer.h +0 -42
  114. package/ReactCommon/jsinspector-modern/tracing/TracingState.h +0 -24
@@ -0,0 +1,165 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #include "HostTracingProfileSerializer.h"
9
+ #include "RuntimeSamplingProfileTraceEventSerializer.h"
10
+ #include "TraceEventGenerator.h"
11
+ #include "TraceEventSerializer.h"
12
+
13
+ namespace facebook::react::jsinspector_modern::tracing {
14
+
15
+ namespace {
16
+
17
+ /**
18
+ * Hardcoded layer tree ID for all recorded frames.
19
+ * https://chromedevtools.github.io/devtools-protocol/tot/LayerTree/
20
+ */
21
+ constexpr int FALLBACK_LAYER_TREE_ID = 1;
22
+
23
+ } // namespace
24
+
25
+ /* static */ void HostTracingProfileSerializer::emitAsDataCollectedChunks(
26
+ HostTracingProfile&& hostTracingProfile,
27
+ const std::function<void(folly::dynamic&&)>& chunkCallback,
28
+ size_t maxChunkBytes,
29
+ uint16_t profileTraceEventsChunkSize) {
30
+ emitFrameTimings(
31
+ std::move(hostTracingProfile.frameTimings),
32
+ hostTracingProfile.processId,
33
+ hostTracingProfile.startTime,
34
+ chunkCallback,
35
+ maxChunkBytes);
36
+
37
+ auto instancesProfiles =
38
+ std::move(hostTracingProfile.instanceTracingProfiles);
39
+ IdGenerator profileIdGenerator;
40
+
41
+ for (auto& instanceProfile : instancesProfiles) {
42
+ emitPerformanceTraceEvents(
43
+ std::move(instanceProfile.performanceTraceEvents),
44
+ chunkCallback,
45
+ maxChunkBytes);
46
+ }
47
+
48
+ RuntimeSamplingProfileTraceEventSerializer::serializeAndDispatch(
49
+ std::move(hostTracingProfile.runtimeSamplingProfiles),
50
+ profileIdGenerator,
51
+ hostTracingProfile.startTime,
52
+ chunkCallback,
53
+ profileTraceEventsChunkSize);
54
+ }
55
+
56
+ /* static */ void HostTracingProfileSerializer::emitPerformanceTraceEvents(
57
+ std::vector<TraceEvent>&& events,
58
+ const std::function<void(folly::dynamic&&)>& chunkCallback,
59
+ size_t maxChunkBytes) {
60
+ folly::dynamic chunk = folly::dynamic::array();
61
+ size_t currentChunkBytes = 0;
62
+
63
+ for (auto& event : events) {
64
+ auto serializedEvent = TraceEventSerializer::serialize(std::move(event));
65
+ size_t eventBytes = TraceEventSerializer::estimateJsonSize(serializedEvent);
66
+
67
+ if (currentChunkBytes + eventBytes > maxChunkBytes && !chunk.empty()) {
68
+ chunkCallback(std::move(chunk));
69
+ chunk = folly::dynamic::array();
70
+ currentChunkBytes = 0;
71
+ }
72
+
73
+ chunk.push_back(std::move(serializedEvent));
74
+ currentChunkBytes += eventBytes;
75
+ }
76
+
77
+ if (!chunk.empty()) {
78
+ chunkCallback(std::move(chunk));
79
+ }
80
+ }
81
+
82
+ /* static */ void HostTracingProfileSerializer::emitFrameTimings(
83
+ std::vector<FrameTimingSequence>&& frameTimings,
84
+ ProcessId processId,
85
+ HighResTimeStamp recordingStartTimestamp,
86
+ const std::function<void(folly::dynamic&& chunk)>& chunkCallback,
87
+ size_t maxChunkBytes) {
88
+ if (frameTimings.empty()) {
89
+ return;
90
+ }
91
+
92
+ folly::dynamic chunk = folly::dynamic::array();
93
+ size_t currentChunkBytes = 0;
94
+
95
+ auto setLayerTreeIdEvent = TraceEventGenerator::createSetLayerTreeIdEvent(
96
+ "", // Hardcoded frame name for the default (and only) layer.
97
+ FALLBACK_LAYER_TREE_ID,
98
+ processId,
99
+ frameTimings.front().threadId,
100
+ recordingStartTimestamp);
101
+ auto serializedSetLayerTreeId =
102
+ TraceEventSerializer::serialize(std::move(setLayerTreeIdEvent));
103
+ currentChunkBytes +=
104
+ TraceEventSerializer::estimateJsonSize(serializedSetLayerTreeId);
105
+ chunk.push_back(std::move(serializedSetLayerTreeId));
106
+
107
+ for (auto&& frameTimingSequence : frameTimings) {
108
+ // Serialize all events for this frame.
109
+ folly::dynamic frameEvents = folly::dynamic::array();
110
+ size_t totalFrameBytes = 0;
111
+
112
+ auto [beginDrawingEvent, endDrawingEvent] =
113
+ TraceEventGenerator::createFrameTimingsEvents(
114
+ frameTimingSequence.id,
115
+ FALLBACK_LAYER_TREE_ID,
116
+ frameTimingSequence.beginTimestamp,
117
+ frameTimingSequence.endTimestamp,
118
+ processId,
119
+ frameTimingSequence.threadId);
120
+
121
+ auto serializedBegin =
122
+ TraceEventSerializer::serialize(std::move(beginDrawingEvent));
123
+ totalFrameBytes += TraceEventSerializer::estimateJsonSize(serializedBegin);
124
+ frameEvents.push_back(std::move(serializedBegin));
125
+
126
+ auto serializedEnd =
127
+ TraceEventSerializer::serialize(std::move(endDrawingEvent));
128
+ totalFrameBytes += TraceEventSerializer::estimateJsonSize(serializedEnd);
129
+ frameEvents.push_back(std::move(serializedEnd));
130
+
131
+ if (frameTimingSequence.screenshot.has_value()) {
132
+ auto screenshotEvent = TraceEventGenerator::createScreenshotEvent(
133
+ frameTimingSequence.id,
134
+ FALLBACK_LAYER_TREE_ID,
135
+ std::move(frameTimingSequence.screenshot.value()),
136
+ frameTimingSequence.endTimestamp,
137
+ processId,
138
+ frameTimingSequence.threadId);
139
+
140
+ auto serializedScreenshot =
141
+ TraceEventSerializer::serialize(std::move(screenshotEvent));
142
+ totalFrameBytes +=
143
+ TraceEventSerializer::estimateJsonSize(serializedScreenshot);
144
+ frameEvents.push_back(std::move(serializedScreenshot));
145
+ }
146
+
147
+ // Flush current chunk if adding this frame would exceed the limit.
148
+ if (currentChunkBytes + totalFrameBytes > maxChunkBytes && !chunk.empty()) {
149
+ chunkCallback(std::move(chunk));
150
+ chunk = folly::dynamic::array();
151
+ currentChunkBytes = 0;
152
+ }
153
+
154
+ for (auto& frameEvent : frameEvents) {
155
+ chunk.push_back(std::move(frameEvent));
156
+ }
157
+ currentChunkBytes += totalFrameBytes;
158
+ }
159
+
160
+ if (!chunk.empty()) {
161
+ chunkCallback(std::move(chunk));
162
+ }
163
+ }
164
+
165
+ } // namespace facebook::react::jsinspector_modern::tracing
@@ -0,0 +1,50 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include "FrameTimingSequence.h"
11
+ #include "HostTracingProfile.h"
12
+ #include "TraceEvent.h"
13
+
14
+ #include <folly/dynamic.h>
15
+ #include <vector>
16
+
17
+ namespace facebook::react::jsinspector_modern::tracing {
18
+
19
+ /**
20
+ * A serializer for HostTracingProfile that can be used for transforming the
21
+ * profile into sequence of serialized Trace Events.
22
+ */
23
+ class HostTracingProfileSerializer {
24
+ public:
25
+ /**
26
+ * Transforms the profile into a sequence of serialized Trace Events, which
27
+ * is split in chunks of at most \p maxChunkBytes serialized bytes or
28
+ * \p profileTraceEventsChunkSize events, depending on type, and sent with
29
+ * \p chunkCallback.
30
+ */
31
+ static void emitAsDataCollectedChunks(
32
+ HostTracingProfile &&hostTracingProfile,
33
+ const std::function<void(folly::dynamic &&chunk)> &chunkCallback,
34
+ size_t maxChunkBytes,
35
+ uint16_t profileTraceEventsChunkSize);
36
+
37
+ static void emitPerformanceTraceEvents(
38
+ std::vector<TraceEvent> &&events,
39
+ const std::function<void(folly::dynamic &&chunk)> &chunkCallback,
40
+ size_t maxChunkBytes);
41
+
42
+ static void emitFrameTimings(
43
+ std::vector<FrameTimingSequence> &&frameTimings,
44
+ ProcessId processId,
45
+ HighResTimeStamp recordingStartTimestamp,
46
+ const std::function<void(folly::dynamic &&chunk)> &chunkCallback,
47
+ size_t maxChunkBytes);
48
+ };
49
+
50
+ } // namespace facebook::react::jsinspector_modern::tracing
@@ -7,7 +7,9 @@
7
7
 
8
8
  #include "PerformanceTracer.h"
9
9
  #include "Timing.h"
10
+ #include "TraceEventGenerator.h"
10
11
  #include "TraceEventSerializer.h"
12
+ #include "TracingCategory.h"
11
13
 
12
14
  #include <jsinspector-modern/network/CdpNetwork.h>
13
15
  #include <jsinspector-modern/network/HttpUtils.h>
@@ -138,7 +140,7 @@ std::optional<std::vector<TraceEvent>> PerformanceTracer::stopTracing() {
138
140
  events.emplace_back(
139
141
  TraceEvent{
140
142
  .name = "TracingStartedInPage",
141
- .cat = "disabled-by-default-devtools.timeline",
143
+ .cat = {Category::HiddenTimeline},
142
144
  .ph = 'I',
143
145
  .ts = currentTraceStartTime,
144
146
  .pid = processId_,
@@ -149,7 +151,7 @@ std::optional<std::vector<TraceEvent>> PerformanceTracer::stopTracing() {
149
151
  events.emplace_back(
150
152
  TraceEvent{
151
153
  .name = "ReactNative-TracingStopped",
152
- .cat = "disabled-by-default-devtools.timeline",
154
+ .cat = {Category::HiddenTimeline},
153
155
  .ph = 'I',
154
156
  .ts = currentTraceEndTime,
155
157
  .pid = processId_,
@@ -370,7 +372,7 @@ void PerformanceTracer::reportResourceFinish(
370
372
  return TraceEvent{
371
373
  .id = profileId,
372
374
  .name = "Profile",
373
- .cat = "disabled-by-default-v8.cpu_profiler",
375
+ .cat = {Category::JavaScriptSampling},
374
376
  .ph = 'P',
375
377
  .ts = profileTimestamp,
376
378
  .pid = processId,
@@ -393,7 +395,7 @@ PerformanceTracer::constructRuntimeProfileChunkTraceEvent(
393
395
  return TraceEvent{
394
396
  .id = profileId,
395
397
  .name = "ProfileChunk",
396
- .cat = "disabled-by-default-v8.cpu_profiler",
398
+ .cat = {Category::JavaScriptSampling},
397
399
  .ph = 'P',
398
400
  .ts = chunkTimestamp,
399
401
  .pid = processId,
@@ -525,7 +527,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
525
527
  events.emplace_back(
526
528
  TraceEvent{
527
529
  .name = "RunTask",
528
- .cat = "disabled-by-default-devtools.timeline",
530
+ .cat = {Category::HiddenTimeline},
529
531
  .ph = 'X',
530
532
  .ts = event.start,
531
533
  .pid = processId_,
@@ -537,7 +539,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
537
539
  events.emplace_back(
538
540
  TraceEvent{
539
541
  .name = "RunMicrotasks",
540
- .cat = "v8.execute",
542
+ .cat = {Category::RuntimeExecution},
541
543
  .ph = 'X',
542
544
  .ts = event.start,
543
545
  .pid = processId_,
@@ -557,7 +559,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
557
559
  events.emplace_back(
558
560
  TraceEvent{
559
561
  .name = std::move(event.name),
560
- .cat = "blink.user_timing",
562
+ .cat = {Category::UserTiming},
561
563
  .ph = 'I',
562
564
  .ts = event.start,
563
565
  .pid = processId_,
@@ -578,7 +580,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
578
580
  TraceEvent{
579
581
  .id = eventId,
580
582
  .name = event.name,
581
- .cat = "blink.user_timing",
583
+ .cat = {Category::UserTiming},
582
584
  .ph = 'b',
583
585
  .ts = event.start,
584
586
  .pid = processId_,
@@ -589,7 +591,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
589
591
  TraceEvent{
590
592
  .id = eventId,
591
593
  .name = std::move(event.name),
592
- .cat = "blink.user_timing",
594
+ .cat = {Category::UserTiming},
593
595
  .ph = 'e',
594
596
  .ts = event.start + event.duration,
595
597
  .pid = processId_,
@@ -629,7 +631,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
629
631
  events.emplace_back(
630
632
  TraceEvent{
631
633
  .name = "TimeStamp",
632
- .cat = "devtools.timeline",
634
+ .cat = {Category::Timeline},
633
635
  .ph = 'I',
634
636
  .ts = event.createdAt,
635
637
  .pid = processId_,
@@ -664,7 +666,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
664
666
  events.emplace_back(
665
667
  TraceEvent{
666
668
  .name = "TimeStamp",
667
- .cat = "devtools.timeline",
669
+ .cat = {Category::Timeline},
668
670
  .ph = 'I',
669
671
  .ts = event.createdAt,
670
672
  .pid = processId_,
@@ -684,7 +686,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
684
686
  events.emplace_back(
685
687
  TraceEvent{
686
688
  .name = "ResourceSendRequest",
687
- .cat = "devtools.timeline",
689
+ .cat = {Category::Timeline},
688
690
  .ph = 'I',
689
691
  .ts = event.start,
690
692
  .pid = processId_,
@@ -710,7 +712,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
710
712
  events.emplace_back(
711
713
  TraceEvent{
712
714
  .name = "ResourceReceiveResponse",
713
- .cat = "devtools.timeline",
715
+ .cat = {Category::Timeline},
714
716
  .ph = 'I',
715
717
  .ts = event.start,
716
718
  .pid = processId_,
@@ -728,7 +730,7 @@ void PerformanceTracer::enqueueTraceEventsFromPerformanceTracerEvent(
728
730
  events.emplace_back(
729
731
  TraceEvent{
730
732
  .name = "ResourceFinish",
731
- .cat = "devtools.timeline",
733
+ .cat = {Category::Timeline},
732
734
  .ph = 'I',
733
735
  .ts = event.start,
734
736
  .pid = processId_,
@@ -0,0 +1,113 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include <folly/dynamic.h>
11
+
12
+ #include <jsinspector-modern/tracing/PerformanceTracer.h>
13
+
14
+ #include <string_view>
15
+
16
+ namespace facebook::react::jsinspector_modern::tracing {
17
+
18
+ /**
19
+ * This is a RAII class that reports a timeStamp block to the React Native
20
+ * Performance Tracer.
21
+ *
22
+ * @example
23
+ * {
24
+ * PerformanceTracerSection s("name", "track", "track group");
25
+ * // do something
26
+ * }
27
+ */
28
+ template <typename... Args>
29
+ class PerformanceTracerSection {
30
+ public:
31
+ explicit PerformanceTracerSection(
32
+ const char *name,
33
+ const char *track = nullptr,
34
+ const char *trackGroup = nullptr,
35
+ const char *color = nullptr,
36
+ Args... args) noexcept
37
+ : name_(name), track_(track), trackGroup_(trackGroup), color_(color), args_(std::move(args)...)
38
+ {
39
+ static_assert(
40
+ sizeof...(Args) % 2 == 0,
41
+ "PerformanceTracerSection expects an even number of variadic args representing [name, value] pairs.");
42
+ }
43
+
44
+ // Non-movable
45
+ PerformanceTracerSection(const PerformanceTracerSection &) = delete;
46
+ PerformanceTracerSection(PerformanceTracerSection &&) = delete;
47
+
48
+ // Non-copyable
49
+ PerformanceTracerSection &operator=(const PerformanceTracerSection &) = delete;
50
+ PerformanceTracerSection &operator=(PerformanceTracerSection &&) = delete;
51
+
52
+ ~PerformanceTracerSection() noexcept
53
+ {
54
+ auto &tracer = PerformanceTracer::getInstance();
55
+ if (!tracer.isTracing()) {
56
+ return;
57
+ }
58
+
59
+ auto endTime = HighResTimeStamp::now();
60
+
61
+ // Slow path when passing properties
62
+ if constexpr (sizeof...(Args) > 0) {
63
+ auto properties = folly::dynamic::array();
64
+ std::apply(
65
+ [&](const auto &...elems) {
66
+ size_t idx = 0;
67
+ (((idx % 2 == 0) ? properties.push_back(folly::dynamic::array(elems))
68
+ : properties[properties.size() - 1].push_back(elems),
69
+ ++idx),
70
+ ...);
71
+ },
72
+ args_);
73
+
74
+ folly::dynamic devtools = folly::dynamic::object();
75
+ devtools["properties"] = std::move(properties);
76
+
77
+ if (track_ != nullptr) {
78
+ devtools["track"] = track_;
79
+ }
80
+
81
+ if (trackGroup_ != nullptr) {
82
+ devtools["trackGroup"] = trackGroup_;
83
+ }
84
+
85
+ if (color_ != nullptr) {
86
+ devtools["color"] = color_;
87
+ }
88
+
89
+ folly::dynamic detail = folly::dynamic::object();
90
+ detail["devtools"] = std::move(devtools);
91
+
92
+ tracer.reportMeasure(std::string(name_), startTime_, endTime - startTime_, std::move(detail));
93
+ } else {
94
+ tracer.reportTimeStamp(
95
+ std::string(name_),
96
+ startTime_,
97
+ endTime,
98
+ track_ != nullptr ? std::optional{track_} : std::nullopt,
99
+ trackGroup_ != nullptr ? std::optional{trackGroup_} : std::nullopt,
100
+ color_ != nullptr ? getConsoleTimeStampColorFromString(color_) : std::nullopt);
101
+ }
102
+ }
103
+
104
+ private:
105
+ HighResTimeStamp startTime_{HighResTimeStamp::now()};
106
+ std::string_view name_;
107
+ const char *track_;
108
+ const char *trackGroup_;
109
+ const char *color_;
110
+ std::tuple<Args...> args_;
111
+ };
112
+
113
+ } // namespace facebook::react::jsinspector_modern::tracing
@@ -47,6 +47,7 @@ Pod::Spec.new do |s|
47
47
  s.dependency "React-jsi"
48
48
  s.dependency "React-oscompat"
49
49
  s.dependency "React-timing"
50
+ add_dependency(s, "React-utils", :additional_framework_paths => ["react/utils/platform/ios"])
50
51
 
51
52
  if use_hermes()
52
53
  s.dependency "hermes-engine"
@@ -0,0 +1,158 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include <algorithm>
11
+ #include <functional>
12
+ #include <optional>
13
+ #include <vector>
14
+
15
+ #include <react/timing/primitives.h>
16
+
17
+ namespace facebook::react::jsinspector_modern::tracing {
18
+
19
+ /**
20
+ * The currentBufferStartTime_ is initialized once first element is pushed.
21
+ */
22
+ constexpr HighResTimeStamp kCurrentBufferStartTimeUninitialized = HighResTimeStamp::min();
23
+
24
+ template <typename T>
25
+ class TimeWindowedBuffer {
26
+ public:
27
+ using TimestampAccessor = std::function<HighResTimeStamp(const T &)>;
28
+
29
+ TimeWindowedBuffer() : timestampAccessor_(std::nullopt), windowSize_(std::nullopt) {}
30
+
31
+ TimeWindowedBuffer(TimestampAccessor timestampAccessor, HighResDuration windowSize)
32
+ : timestampAccessor_(std::move(timestampAccessor)), windowSize_(windowSize)
33
+ {
34
+ }
35
+
36
+ void push(const T &element)
37
+ {
38
+ if (timestampAccessor_) {
39
+ auto timestamp = (*timestampAccessor_)(element);
40
+ enqueueElement(element, timestamp);
41
+ } else {
42
+ enqueueElement(element, HighResTimeStamp::now());
43
+ }
44
+ }
45
+
46
+ void push(T &&element)
47
+ {
48
+ if (timestampAccessor_) {
49
+ auto timestamp = (*timestampAccessor_)(element);
50
+ enqueueElement(std::move(element), timestamp);
51
+ } else {
52
+ enqueueElement(std::move(element), HighResTimeStamp::now());
53
+ }
54
+ }
55
+
56
+ void clear()
57
+ {
58
+ primaryBuffer_.clear();
59
+ alternativeBuffer_.clear();
60
+ currentBufferIndex_ = BufferIndex::Primary;
61
+ currentBufferStartTime_ = kCurrentBufferStartTimeUninitialized;
62
+ }
63
+
64
+ /**
65
+ * Forces immediate removal of elements that are outside the time window.
66
+ * The right boundary of the window is the reference timestamp passed as an argument.
67
+ */
68
+ std::vector<T> pruneExpiredAndExtract(HighResTimeStamp windowRightBoundary = HighResTimeStamp::now())
69
+ {
70
+ std::vector<T> result;
71
+
72
+ for (auto &wrappedElement : getPreviousBuffer()) {
73
+ if (isInsideTimeWindow(wrappedElement, windowRightBoundary)) {
74
+ result.push_back(std::move(wrappedElement.element));
75
+ }
76
+ }
77
+
78
+ for (auto &wrappedElement : getCurrentBuffer()) {
79
+ if (isInsideTimeWindow(wrappedElement, windowRightBoundary)) {
80
+ result.push_back(std::move(wrappedElement.element));
81
+ }
82
+ }
83
+
84
+ clear();
85
+ return result;
86
+ }
87
+
88
+ private:
89
+ enum class BufferIndex { Primary, Alternative };
90
+
91
+ struct TimestampedElement {
92
+ T element;
93
+ HighResTimeStamp timestamp;
94
+ };
95
+
96
+ std::vector<TimestampedElement> &getCurrentBuffer()
97
+ {
98
+ return currentBufferIndex_ == BufferIndex::Primary ? primaryBuffer_ : alternativeBuffer_;
99
+ }
100
+
101
+ std::vector<TimestampedElement> &getPreviousBuffer()
102
+ {
103
+ return currentBufferIndex_ == BufferIndex::Primary ? alternativeBuffer_ : primaryBuffer_;
104
+ }
105
+
106
+ void enqueueElement(const T &element, HighResTimeStamp timestamp)
107
+ {
108
+ if (windowSize_) {
109
+ if (currentBufferStartTime_ == kCurrentBufferStartTimeUninitialized) {
110
+ currentBufferStartTime_ = timestamp;
111
+ } else if (timestamp > currentBufferStartTime_ + *windowSize_) {
112
+ // We moved past the current buffer. We need to switch the other buffer as current.
113
+ currentBufferIndex_ =
114
+ currentBufferIndex_ == BufferIndex::Primary ? BufferIndex::Alternative : BufferIndex::Primary;
115
+ getCurrentBuffer().clear();
116
+ currentBufferStartTime_ = timestamp;
117
+ }
118
+ }
119
+
120
+ getCurrentBuffer().push_back({element, timestamp});
121
+ }
122
+
123
+ void enqueueElement(T &&element, HighResTimeStamp timestamp)
124
+ {
125
+ if (windowSize_) {
126
+ if (currentBufferStartTime_ == kCurrentBufferStartTimeUninitialized) {
127
+ currentBufferStartTime_ = timestamp;
128
+ } else if (timestamp > currentBufferStartTime_ + *windowSize_) {
129
+ // We moved past the current buffer. We need to switch the other buffer as current.
130
+ currentBufferIndex_ =
131
+ currentBufferIndex_ == BufferIndex::Primary ? BufferIndex::Alternative : BufferIndex::Primary;
132
+ getCurrentBuffer().clear();
133
+ currentBufferStartTime_ = timestamp;
134
+ }
135
+ }
136
+
137
+ getCurrentBuffer().push_back({std::move(element), timestamp});
138
+ }
139
+
140
+ bool isInsideTimeWindow(const TimestampedElement &element, HighResTimeStamp windowRightBoundary) const
141
+ {
142
+ if (!windowSize_) {
143
+ return true;
144
+ }
145
+
146
+ return element.timestamp >= windowRightBoundary - *windowSize_ && element.timestamp <= windowRightBoundary;
147
+ }
148
+
149
+ std::optional<TimestampAccessor> timestampAccessor_;
150
+ std::optional<HighResDuration> windowSize_;
151
+
152
+ std::vector<TimestampedElement> primaryBuffer_;
153
+ std::vector<TimestampedElement> alternativeBuffer_;
154
+ BufferIndex currentBufferIndex_ = BufferIndex::Primary;
155
+ HighResTimeStamp currentBufferStartTime_{kCurrentBufferStartTimeUninitialized};
156
+ };
157
+
158
+ } // namespace facebook::react::jsinspector_modern::tracing
@@ -7,6 +7,7 @@
7
7
 
8
8
  #pragma once
9
9
 
10
+ #include <jsinspector-modern/tracing/TracingCategory.h>
10
11
  #include <react/timing/primitives.h>
11
12
 
12
13
  #include <folly/dynamic.h>
@@ -40,7 +41,7 @@ struct TraceEvent {
40
41
  * A comma separated list of categories for the event, configuring how
41
42
  * events are shown in the Trace Viewer UI.
42
43
  */
43
- std::string cat;
44
+ Categories cat;
44
45
 
45
46
  /**
46
47
  * The event type. This is a single character which changes depending on the