@react-native-firebase/perf 26.3.2 → 26.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [26.4.0](https://github.com/invertase/react-native-firebase/compare/v26.3.3...v26.4.0) (2026-09-05)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **perf, android:** use RNFBHandleMap for traces and http metrics ([60b6e7d](https://github.com/invertase/react-native-firebase/commit/60b6e7daa005d137228763291be0db75997b9162))
11
+
12
+ ## [26.3.3](https://github.com/invertase/react-native-firebase/compare/v26.3.2...v26.3.3) (2026-09-01)
13
+
14
+ ### Bug Fixes
15
+
16
+ - **ios:** align TurboModule constants return type with generated spec ([c79e1d2](https://github.com/invertase/react-native-firebase/commit/c79e1d2bc43b00a6ef61d38a294feceaed447740)), closes [#9212](https://github.com/invertase/react-native-firebase/issues/9212)
17
+
18
+ ### Reverts
19
+
20
+ - Revert "chore(release): release packages" ([0a85268](https://github.com/invertase/react-native-firebase/commit/0a85268ae21c706cf1392eaa5b088e85c3273cb7))
21
+
6
22
  ## [26.3.2](https://github.com/invertase/react-native-firebase/compare/v26.3.1...v26.3.2) (2026-08-21)
7
23
 
8
24
  **Note:** Version bump only for package @react-native-firebase/perf
package/RNFBPerf.podspec CHANGED
@@ -31,7 +31,7 @@ Pod::Spec.new do |s|
31
31
  s.tvos.deployment_target = firebase_tvos_target
32
32
  s.source_files = 'ios/**/*.{h,m,mm,cpp,swift}'
33
33
  s.private_header_files = "ios/**/*.h"
34
- s.exclude_files = 'ios/generated/RCTThirdPartyComponentsProvider.*', 'ios/generated/RCTAppDependencyProvider.*', 'ios/generated/RCTModuleProviders.*', 'ios/generated/RCTModulesConformingToProtocolsProvider.*', 'ios/generated/RCTUnstableModulesRequiringMainQueueSetupProvider.*'
34
+ s.exclude_files = 'ios/generated/RCTThirdPartyComponentsProvider.*', 'ios/generated/RCTAppDependencyProvider.*', 'ios/generated/RCTModuleProviders.*', 'ios/generated/RCTModulesConformingToProtocolsProvider.*', 'ios/generated/RCTUnstableModulesRequiringMainQueueSetupProvider.*', 'ios/*UnitTests/**'
35
35
 
36
36
  # Must be set before install_modules_dependencies so RN can append use_frameworks
37
37
  # HEADER_SEARCH_PATHS (React-debug etc.). Assigning after overwrites those paths
@@ -135,6 +135,8 @@ dependencies {
135
135
  api appProject
136
136
  implementation platform("com.google.firebase:firebase-bom:${ReactNative.ext.getVersion("firebase", "bom")}")
137
137
  implementation "com.google.firebase:firebase-perf"
138
+
139
+ testImplementation "junit:junit:4.13.2"
138
140
  }
139
141
 
140
142
  ReactNative.shared.applyPackageVersion()
@@ -0,0 +1,72 @@
1
+ package io.invertase.firebase.perf;
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ */
19
+
20
+ import io.invertase.firebase.common.RNFBHandleCollisionException;
21
+ import io.invertase.firebase.common.RNFBHandleMap;
22
+ import java.util.List;
23
+ import java.util.function.Predicate;
24
+
25
+ /**
26
+ * Perf id → metric handle map (traces, screen traces, HTTP metrics). Module start paths use {@link
27
+ * #putReplacing} (last wins, stop displaced outside lock). Unique {@link #put} / {@link
28
+ * #putOrDiscard} remain for tests. Callers {@link #get} then {@link #take} then stop outside the
29
+ * HandleMap lock. Tear-down discards via {@link #takeAll} without stopping (matches prior
30
+ * SparseArray clear).
31
+ */
32
+ final class RNFBPerfHandleRegistry<V> {
33
+ private final RNFBHandleMap<Integer, V> map = new RNFBHandleMap<>();
34
+
35
+ void put(int id, V handle) throws RNFBHandleCollisionException {
36
+ map.put(id, handle);
37
+ }
38
+
39
+ /**
40
+ * Unique put. On collision, drop the incoming handle without stopping and leave the existing
41
+ * mapping.
42
+ *
43
+ * @return true if stored
44
+ */
45
+ boolean putOrDiscard(int id, V handle) {
46
+ return map.putIfAbsent(id, handle);
47
+ }
48
+
49
+ /**
50
+ * Atomically replaces the mapping for {@code id} (last wins). Returns the displaced handle, or
51
+ * {@code null} if the id was free. Stop the displaced handle after this method returns.
52
+ */
53
+ V putReplacing(int id, V handle) {
54
+ return map.putReplacing(id, handle);
55
+ }
56
+
57
+ V get(int id) {
58
+ return map.get(id);
59
+ }
60
+
61
+ V take(int id) {
62
+ return map.take(id);
63
+ }
64
+
65
+ V takeIf(int id, Predicate<V> shouldTake) {
66
+ return map.takeIf(id, shouldTake);
67
+ }
68
+
69
+ List<V> takeAll() {
70
+ return map.takeAll();
71
+ }
72
+ }
@@ -20,7 +20,6 @@ package io.invertase.firebase.perf;
20
20
  import android.app.Activity;
21
21
  import android.content.Context;
22
22
  import android.os.Bundle;
23
- import android.util.SparseArray;
24
23
  import com.google.android.gms.tasks.Task;
25
24
  import com.google.android.gms.tasks.Tasks;
26
25
  import com.google.firebase.perf.FirebasePerformance;
@@ -33,9 +32,11 @@ import java.util.Objects;
33
32
  import java.util.Set;
34
33
 
35
34
  public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
36
- private static SparseArray<Trace> traces = new SparseArray<>();
37
- private static SparseArray<ScreenTrace> screenTraces = new SparseArray<>();
38
- private static SparseArray<HttpMetric> httpMetrics = new SparseArray<>();
35
+ private static final RNFBPerfHandleRegistry<Trace> traces = new RNFBPerfHandleRegistry<>();
36
+ private static final RNFBPerfHandleRegistry<ScreenTrace> screenTraces =
37
+ new RNFBPerfHandleRegistry<>();
38
+ private static final RNFBPerfHandleRegistry<HttpMetric> httpMetrics =
39
+ new RNFBPerfHandleRegistry<>();
39
40
 
40
41
  UniversalFirebasePerfModule(Context context, String serviceName) {
41
42
  super(context, serviceName);
@@ -44,9 +45,10 @@ public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
44
45
  @Override
45
46
  public void onTearDown() {
46
47
  super.onTearDown();
47
- traces.clear();
48
- httpMetrics.clear();
49
- screenTraces.clear();
48
+ // Drop mappings only — matches prior SparseArray.clear() (no stop/cancel).
49
+ traces.takeAll();
50
+ httpMetrics.takeAll();
51
+ screenTraces.takeAll();
50
52
  }
51
53
 
52
54
  @Override
@@ -72,9 +74,7 @@ public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
72
74
  () -> {
73
75
  Trace trace = FirebasePerformance.getInstance().newTrace(identifier);
74
76
  trace.start();
75
-
76
- traces.put(id, trace);
77
-
77
+ registerStartedTrace(id, trace);
78
78
  return null;
79
79
  });
80
80
  }
@@ -101,8 +101,10 @@ public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
101
101
  attributeKey, (String) Objects.requireNonNull(attributes.get(attributeKey)));
102
102
  }
103
103
 
104
- trace.stop();
105
- traces.remove(id);
104
+ Trace taken = traces.takeIf(id, t -> t == trace);
105
+ if (taken != null) {
106
+ taken.stop();
107
+ }
106
108
 
107
109
  return null;
108
110
  });
@@ -113,8 +115,7 @@ public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
113
115
  () -> {
114
116
  ScreenTrace screenTrace = new ScreenTrace(activity, identifier);
115
117
  screenTrace.recordScreenTrace();
116
- screenTraces.put(id, screenTrace);
117
-
118
+ registerRecordedScreenTrace(id, screenTrace);
118
119
  return null;
119
120
  });
120
121
  }
@@ -127,8 +128,11 @@ public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
127
128
  if (trace == null) {
128
129
  return null;
129
130
  }
130
- trace.sendScreenTrace();
131
- screenTraces.remove(id);
131
+
132
+ ScreenTrace taken = screenTraces.takeIf(id, t -> t == trace);
133
+ if (taken != null) {
134
+ taken.sendScreenTrace();
135
+ }
132
136
 
133
137
  return null;
134
138
  });
@@ -139,7 +143,7 @@ public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
139
143
  () -> {
140
144
  HttpMetric httpMetric = FirebasePerformance.getInstance().newHttpMetric(url, httpMethod);
141
145
  httpMetric.start();
142
- httpMetrics.put(id, httpMetric);
146
+ registerStartedHttpMetric(id, httpMetric);
143
147
  return null;
144
148
  });
145
149
  }
@@ -178,8 +182,10 @@ public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
178
182
  attributeKey, Objects.requireNonNull(attributes.getString(attributeKey)));
179
183
  }
180
184
 
181
- httpMetric.stop();
182
- httpMetrics.remove(id);
185
+ HttpMetric taken = httpMetrics.takeIf(id, m -> m == httpMetric);
186
+ if (taken != null) {
187
+ taken.stop();
188
+ }
183
189
 
184
190
  return null;
185
191
  });
@@ -190,7 +196,7 @@ public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
190
196
  void startTraceSync(int id, String identifier) {
191
197
  Trace trace = FirebasePerformance.getInstance().newTrace(identifier);
192
198
  trace.start();
193
- traces.put(id, trace);
199
+ registerStartedTrace(id, trace);
194
200
  }
195
201
 
196
202
  void stopTraceSync(int id, Bundle metrics, Bundle attributes) {
@@ -213,14 +219,16 @@ public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
213
219
  attributeKey, (String) Objects.requireNonNull(attributes.get(attributeKey)));
214
220
  }
215
221
 
216
- trace.stop();
217
- traces.remove(id);
222
+ Trace taken = traces.takeIf(id, t -> t == trace);
223
+ if (taken != null) {
224
+ taken.stop();
225
+ }
218
226
  }
219
227
 
220
228
  void startScreenTraceSync(Activity activity, int id, String identifier) {
221
229
  ScreenTrace screenTrace = new ScreenTrace(activity, identifier);
222
230
  screenTrace.recordScreenTrace();
223
- screenTraces.put(id, screenTrace);
231
+ registerRecordedScreenTrace(id, screenTrace);
224
232
  }
225
233
 
226
234
  void stopScreenTraceSync(int id) {
@@ -229,14 +237,17 @@ public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
229
237
  if (trace == null) {
230
238
  return;
231
239
  }
232
- trace.sendScreenTrace();
233
- screenTraces.remove(id);
240
+
241
+ ScreenTrace taken = screenTraces.takeIf(id, t -> t == trace);
242
+ if (taken != null) {
243
+ taken.sendScreenTrace();
244
+ }
234
245
  }
235
246
 
236
247
  void startHttpMetricSync(int id, String url, String httpMethod) {
237
248
  HttpMetric httpMetric = FirebasePerformance.getInstance().newHttpMetric(url, httpMethod);
238
249
  httpMetric.start();
239
- httpMetrics.put(id, httpMetric);
250
+ registerStartedHttpMetric(id, httpMetric);
240
251
  }
241
252
 
242
253
  void stopHttpMetricSync(int id, Bundle httpMetricConfig, Bundle attributes) {
@@ -269,7 +280,33 @@ public class UniversalFirebasePerfModule extends UniversalFirebaseModule {
269
280
  attributeKey, Objects.requireNonNull(attributes.getString(attributeKey)));
270
281
  }
271
282
 
272
- httpMetric.stop();
273
- httpMetrics.remove(id);
283
+ HttpMetric taken = httpMetrics.takeIf(id, m -> m == httpMetric);
284
+ if (taken != null) {
285
+ taken.stop();
286
+ }
287
+ }
288
+
289
+ /** Last-wins registration: stop any displaced trace outside the HandleMap lock. */
290
+ private static void registerStartedTrace(int id, Trace trace) {
291
+ Trace displaced = traces.putReplacing(id, trace);
292
+ if (displaced != null) {
293
+ displaced.stop();
294
+ }
295
+ }
296
+
297
+ /** Last-wins registration: stop any displaced HTTP metric outside the HandleMap lock. */
298
+ private static void registerStartedHttpMetric(int id, HttpMetric httpMetric) {
299
+ HttpMetric displaced = httpMetrics.putReplacing(id, httpMetric);
300
+ if (displaced != null) {
301
+ displaced.stop();
302
+ }
303
+ }
304
+
305
+ /** Last-wins registration: finalize any displaced screen trace outside the HandleMap lock. */
306
+ private static void registerRecordedScreenTrace(int id, ScreenTrace screenTrace) {
307
+ ScreenTrace displaced = screenTraces.putReplacing(id, screenTrace);
308
+ if (displaced != null) {
309
+ displaced.sendScreenTrace();
310
+ }
274
311
  }
275
312
  }
@@ -0,0 +1,175 @@
1
+ package io.invertase.firebase.perf;
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ */
19
+
20
+ import static org.junit.Assert.assertEquals;
21
+ import static org.junit.Assert.assertFalse;
22
+ import static org.junit.Assert.assertNull;
23
+ import static org.junit.Assert.assertSame;
24
+ import static org.junit.Assert.assertTrue;
25
+ import static org.junit.Assert.fail;
26
+
27
+ import io.invertase.firebase.common.RNFBHandleCollisionException;
28
+ import java.util.List;
29
+ import org.junit.Test;
30
+
31
+ /**
32
+ * JVM coverage for {@link RNFBPerfHandleRegistry}. Does not instantiate {@code
33
+ * UniversalFirebasePerfModule} / Firebase Perf types — D12.
34
+ */
35
+ public class RNFBPerfHandleRegistryTest {
36
+
37
+ @Test
38
+ public void putTake_happyPath() throws Exception {
39
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
40
+ registry.put(1, "trace");
41
+ assertSame("trace", registry.take(1));
42
+ assertNull(registry.take(1));
43
+ }
44
+
45
+ @Test
46
+ public void put_occupiedId_throwsCollision() throws Exception {
47
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
48
+ registry.put(1, "first");
49
+ try {
50
+ registry.put(1, "second");
51
+ fail("expected RNFBHandleCollisionException");
52
+ } catch (RNFBHandleCollisionException e) {
53
+ assertTrue(e.getMessage().contains("1"));
54
+ assertSame("first", registry.take(1));
55
+ }
56
+ }
57
+
58
+ @Test
59
+ public void take_whenFree_isNull() {
60
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
61
+ assertNull(registry.take(99));
62
+ }
63
+
64
+ @Test
65
+ public void putOrDiscard_storesWhenFree() {
66
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
67
+ assertTrue(registry.putOrDiscard(1, "trace"));
68
+ assertSame("trace", registry.take(1));
69
+ }
70
+
71
+ @Test
72
+ public void putOrDiscard_collision_dropsIncomingWithoutDiscard() throws Exception {
73
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
74
+ registry.put(1, "first");
75
+ assertFalse(registry.putOrDiscard(1, "second"));
76
+ assertSame("first", registry.take(1));
77
+ }
78
+
79
+ @Test
80
+ public void putOrDiscard_collision_nullIncoming_isNoOp() throws Exception {
81
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
82
+ registry.put(1, "first");
83
+ assertFalse(registry.putOrDiscard(1, null));
84
+ assertSame("first", registry.take(1));
85
+ }
86
+
87
+ @Test
88
+ public void putReplacing_whenFree_stores() {
89
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
90
+ assertNull(registry.putReplacing(1, "trace"));
91
+ assertSame("trace", registry.get(1));
92
+ }
93
+
94
+ @Test
95
+ public void putReplacing_whenOccupied_returnsDisplaced() throws Exception {
96
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
97
+ registry.put(1, "first");
98
+ assertSame("first", registry.putReplacing(1, "second"));
99
+ assertSame("second", registry.get(1));
100
+ }
101
+
102
+ @Test
103
+ public void putReplacing_moduleCollisionPattern_stopsDisplacedOutsideLock() throws Exception {
104
+ RNFBPerfHandleRegistry<FakeStoppableHandle> registry = new RNFBPerfHandleRegistry<>();
105
+ FakeStoppableHandle first = new FakeStoppableHandle();
106
+ FakeStoppableHandle second = new FakeStoppableHandle();
107
+ registry.put(1, first);
108
+ FakeStoppableHandle displaced = registry.putReplacing(1, second);
109
+ if (displaced != null) {
110
+ displaced.stop();
111
+ }
112
+ assertEquals(1, first.stopCount);
113
+ assertEquals(0, second.stopCount);
114
+ assertSame(second, registry.get(1));
115
+ }
116
+
117
+ @Test
118
+ public void get_whenFree_isNull() {
119
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
120
+ assertNull(registry.get(99));
121
+ }
122
+
123
+ @Test
124
+ public void get_whenOccupied_returnsHandle() throws Exception {
125
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
126
+ registry.put(1, "trace");
127
+ assertSame("trace", registry.get(1));
128
+ assertSame("trace", registry.take(1));
129
+ }
130
+
131
+ @Test
132
+ public void takeAll_returnsSnapshotAndLeavesEmpty() throws Exception {
133
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
134
+ registry.put(1, "a");
135
+ registry.put(2, "b");
136
+ List<String> remaining = registry.takeAll();
137
+ assertEquals(2, remaining.size());
138
+ assertTrue(remaining.contains("a"));
139
+ assertTrue(remaining.contains("b"));
140
+ assertNull(registry.take(1));
141
+ assertNull(registry.take(2));
142
+ }
143
+
144
+ @Test
145
+ public void takeAll_empty_returnsEmptyList() {
146
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
147
+ assertTrue(registry.takeAll().isEmpty());
148
+ }
149
+
150
+ @Test
151
+ public void takeAll_nullHandle_isIncluded() throws Exception {
152
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
153
+ registry.put(1, null);
154
+ List<String> remaining = registry.takeAll();
155
+ assertEquals(1, remaining.size());
156
+ assertNull(remaining.get(0));
157
+ }
158
+
159
+ @Test
160
+ public void put_afterTake_allowsReuse() throws Exception {
161
+ RNFBPerfHandleRegistry<String> registry = new RNFBPerfHandleRegistry<>();
162
+ registry.put(1, "first");
163
+ assertSame("first", registry.take(1));
164
+ registry.put(1, "second");
165
+ assertSame("second", registry.take(1));
166
+ }
167
+
168
+ private static final class FakeStoppableHandle {
169
+ int stopCount = 0;
170
+
171
+ void stop() {
172
+ stopCount++;
173
+ }
174
+ }
175
+ }
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
 
3
3
  // Generated by genversion.
4
- export const version = '26.3.2';
4
+ export const version = '26.4.0';
5
5
  //# sourceMappingURL=version.js.map
@@ -1,7 +1,7 @@
1
1
  import type { FirebaseApp } from '@react-native-firebase/app';
2
2
  import './types/internal';
3
3
  import type { FirebasePerformance, HttpMetric, HttpMethod, PerformanceSettings, PerformanceTrace, ScreenTrace } from './types/perf';
4
- export declare const SDK_VERSION = "26.3.2";
4
+ export declare const SDK_VERSION = "26.4.0";
5
5
  export declare function getPerformance(app?: FirebaseApp): FirebasePerformance;
6
6
  /**
7
7
  * Creates a Performance Monitoring instance and applies optional settings.
@@ -1,2 +1,2 @@
1
- export declare const version = "26.3.2";
1
+ export declare const version = "26.4.0";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ #import <Foundation/Foundation.h>
19
+
20
+ NS_ASSUME_NONNULL_BEGIN
21
+
22
+ /**
23
+ * Perf trace / HTTP metric handle map. Module start paths use `putReplacing` (last wins, stop
24
+ * displaced outside lock). Unique `put` / `putOrDiscard` remain for tests. Callers `get` then
25
+ * `take` then stop outside the HandleMap lock. Tear-down uses `takeAll` without stopping.
26
+ */
27
+ @interface RNFBPerfHandleRegistry : NSObject
28
+
29
+ - (BOOL)put:(id)key value:(id)value error:(NSError *_Nullable *_Nullable)error;
30
+ /// Unique put. On collision, drop the incoming handle without stopping.
31
+ - (BOOL)putOrDiscard:(id)key value:(id)value;
32
+ /// Last wins. Returns the displaced handle, or nil if the key was free.
33
+ - (nullable id)putReplacing:(id)key value:(id)value;
34
+ - (nullable id)get:(id)key;
35
+ - (nullable id)take:(id)key;
36
+ - (nullable id)takeIf:(id)key when:(BOOL (^)(id value))condition;
37
+ - (NSArray *)takeAll;
38
+
39
+ @end
40
+
41
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ #import "RNFBPerfHandleRegistry.h"
19
+
20
+ #if __has_include("RNFBHandleMap.h")
21
+ #import "RNFBHandleMap.h"
22
+ #else
23
+ #import "RNFBApp/RNFBHandleMap.h"
24
+ #endif
25
+
26
+ @interface RNFBPerfHandleRegistry ()
27
+ @property(nonatomic, strong) RNFBHandleMap *map;
28
+ @end
29
+
30
+ @implementation RNFBPerfHandleRegistry
31
+
32
+ - (instancetype)init {
33
+ self = [super init];
34
+ if (self) {
35
+ _map = [[RNFBHandleMap alloc] init];
36
+ }
37
+ return self;
38
+ }
39
+
40
+ - (BOOL)put:(id)key value:(id)value error:(NSError **)error {
41
+ return [self.map put:key value:value error:error];
42
+ }
43
+
44
+ - (BOOL)putOrDiscard:(id)key value:(id)value {
45
+ return [self.map putIfAbsent:key value:value];
46
+ }
47
+
48
+ - (id)putReplacing:(id)key value:(id)value {
49
+ return [self.map putReplacing:key value:value];
50
+ }
51
+
52
+ - (id)get:(id)key {
53
+ return [self.map get:key];
54
+ }
55
+
56
+ - (id)take:(id)key {
57
+ return [self.map take:key];
58
+ }
59
+
60
+ - (id)takeIf:(id)key when:(BOOL (^)(id))condition {
61
+ return [self.map takeIf:key when:condition];
62
+ }
63
+
64
+ - (NSArray *)takeAll {
65
+ return [self.map takeAll];
66
+ }
67
+
68
+ @end
@@ -35,10 +35,11 @@
35
35
  #define RNFB_PERF_SDK_AVAILABLE 0
36
36
  #endif
37
37
  #import "RNFBApp/RNFBSharedUtils.h"
38
+ #import "RNFBPerfHandleRegistry.h"
38
39
  #import "RNFBPerfModule.h"
39
40
 
40
- static __strong NSMutableDictionary *traces;
41
- static __strong NSMutableDictionary *httpMetrics;
41
+ static RNFBPerfHandleRegistry *traces;
42
+ static RNFBPerfHandleRegistry *httpMetrics;
42
43
 
43
44
  @implementation RNFBPerfModule
44
45
 
@@ -53,23 +54,16 @@ RCT_EXPORT_MODULE(NativeRNFBTurboPerf)
53
54
 
54
55
  static dispatch_once_t onceToken;
55
56
  dispatch_once(&onceToken, ^{
56
- traces = [[NSMutableDictionary alloc] init];
57
- httpMetrics = [[NSMutableDictionary alloc] init];
57
+ traces = [[RNFBPerfHandleRegistry alloc] init];
58
+ httpMetrics = [[RNFBPerfHandleRegistry alloc] init];
58
59
  });
59
60
 
60
61
  return self;
61
62
  }
62
63
 
63
64
  - (void)invalidate {
64
- @synchronized([self class]) {
65
- for (NSString *key in [traces allKeys]) {
66
- [traces removeObjectForKey:key];
67
- }
68
-
69
- for (NSString *key in [httpMetrics allKeys]) {
70
- [httpMetrics removeObjectForKey:key];
71
- }
72
- }
65
+ [traces takeAll];
66
+ [httpMetrics takeAll];
73
67
  }
74
68
 
75
69
  #if !RNFB_PERF_SDK_AVAILABLE
@@ -97,11 +91,11 @@ RCT_EXPORT_MODULE(NativeRNFBTurboPerf)
97
91
  return constants;
98
92
  }
99
93
 
100
- - (facebook::react::ModuleConstants<JS::NativeRNFBTurboPerf::Constants::Builder>)constantsToExport {
94
+ - (facebook::react::ModuleConstants<JS::NativeRNFBTurboPerf::Constants>)constantsToExport {
101
95
  return [_RCTTypedModuleConstants newWithUnsafeDictionary:[self perfConstantsDictionary]];
102
96
  }
103
97
 
104
- - (facebook::react::ModuleConstants<JS::NativeRNFBTurboPerf::Constants::Builder>)getConstants {
98
+ - (facebook::react::ModuleConstants<JS::NativeRNFBTurboPerf::Constants>)getConstants {
105
99
  return [self constantsToExport];
106
100
  }
107
101
 
@@ -141,8 +135,9 @@ RCT_EXPORT_MODULE(NativeRNFBTurboPerf)
141
135
  FIRTrace *trace = [[FIRPerformance sharedInstance] traceWithName:identifier];
142
136
  [trace start];
143
137
 
144
- @synchronized([self class]) {
145
- traces[@((int)id)] = trace;
138
+ FIRTrace *displaced = [traces putReplacing:@((int)id) value:trace];
139
+ if (displaced != nil) {
140
+ [displaced stop];
146
141
  }
147
142
  #else
148
143
  (void)id;
@@ -152,9 +147,10 @@ RCT_EXPORT_MODULE(NativeRNFBTurboPerf)
152
147
 
153
148
  - (void)stopTrace:(double)id traceData:(JS::NativeRNFBTurboPerf::TraceData &)traceData {
154
149
  #if RNFB_PERF_SDK_AVAILABLE
155
- FIRTrace *trace;
156
- @synchronized([self class]) {
157
- trace = traces[@((int)id)];
150
+ NSNumber *traceId = @((int)id);
151
+ FIRTrace *trace = [traces get:traceId];
152
+ if (trace == nil) {
153
+ return;
158
154
  }
159
155
 
160
156
  NSDictionary *metrics = (NSDictionary *)traceData.metrics();
@@ -169,10 +165,13 @@ RCT_EXPORT_MODULE(NativeRNFBTurboPerf)
169
165
  [trace setValue:value forAttribute:attributeName];
170
166
  }];
171
167
 
172
- [trace stop];
173
-
174
- @synchronized([self class]) {
175
- [traces removeObjectForKey:@((int)id)];
168
+ FIRTrace *expected = trace;
169
+ trace = [traces takeIf:traceId
170
+ when:^BOOL(NSObject *value) {
171
+ return value == expected;
172
+ }];
173
+ if (trace != nil) {
174
+ [trace stop];
176
175
  }
177
176
  #else
178
177
  (void)id;
@@ -215,8 +214,9 @@ RCT_EXPORT_MODULE(NativeRNFBTurboPerf)
215
214
  FIRHTTPMetric *httpMetric = [[FIRHTTPMetric alloc] initWithURL:toNSURL HTTPMethod:method];
216
215
  [httpMetric start];
217
216
 
218
- @synchronized([self class]) {
219
- httpMetrics[@((int)id)] = httpMetric;
217
+ FIRHTTPMetric *displaced = [httpMetrics putReplacing:@((int)id) value:httpMetric];
218
+ if (displaced != nil) {
219
+ [displaced stop];
220
220
  }
221
221
  #else
222
222
  (void)id;
@@ -227,9 +227,10 @@ RCT_EXPORT_MODULE(NativeRNFBTurboPerf)
227
227
 
228
228
  - (void)stopHttpMetric:(double)id metricData:(JS::NativeRNFBTurboPerf::HttpMetricData &)metricData {
229
229
  #if RNFB_PERF_SDK_AVAILABLE
230
- FIRHTTPMetric *httpMetric;
231
- @synchronized([self class]) {
232
- httpMetric = httpMetrics[@((int)id)];
230
+ NSNumber *metricId = @((int)id);
231
+ FIRHTTPMetric *httpMetric = [httpMetrics get:metricId];
232
+ if (httpMetric == nil) {
233
+ return;
233
234
  }
234
235
 
235
236
  NSDictionary *attributes = (NSDictionary *)metricData.attributes();
@@ -254,10 +255,13 @@ RCT_EXPORT_MODULE(NativeRNFBTurboPerf)
254
255
  [httpMetric setResponseContentType:metricData.responseContentType()];
255
256
  }
256
257
 
257
- [httpMetric stop];
258
-
259
- @synchronized([self class]) {
260
- [httpMetrics removeObjectForKey:@((int)id)];
258
+ FIRHTTPMetric *expected = httpMetric;
259
+ httpMetric = [httpMetrics takeIf:metricId
260
+ when:^BOOL(NSObject *value) {
261
+ return value == expected;
262
+ }];
263
+ if (httpMetric != nil) {
264
+ [httpMetric stop];
261
265
  }
262
266
  #else
263
267
  (void)id;
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ #import <XCTest/XCTest.h>
19
+
20
+ #import "RNFBHandleMap.h"
21
+ #import "RNFBPerfHandleRegistry.h"
22
+
23
+ @interface FakePerfHandle : NSObject
24
+ @property(nonatomic, assign) NSInteger stopCount;
25
+ - (void)stop;
26
+ @end
27
+
28
+ @implementation FakePerfHandle
29
+ - (void)stop {
30
+ self.stopCount += 1;
31
+ }
32
+ @end
33
+
34
+ @interface RNFBPerfHandleRegistryTests : XCTestCase
35
+ @property(nonatomic, strong) RNFBPerfHandleRegistry *registry;
36
+ @end
37
+
38
+ @implementation RNFBPerfHandleRegistryTests
39
+
40
+ - (void)setUp {
41
+ [super setUp];
42
+ self.registry = [[RNFBPerfHandleRegistry alloc] init];
43
+ }
44
+
45
+ - (void)testPutGetTake_happyPath {
46
+ FakePerfHandle *handle = [[FakePerfHandle alloc] init];
47
+ NSError *error = nil;
48
+ XCTAssertTrue([self.registry put:@1 value:handle error:&error]);
49
+ XCTAssertNil(error);
50
+ XCTAssertEqual(handle, [self.registry get:@1]);
51
+ XCTAssertEqual(handle, [self.registry take:@1]);
52
+ XCTAssertNil([self.registry get:@1]);
53
+ XCTAssertEqual(handle.stopCount, 0);
54
+ }
55
+
56
+ - (void)testPut_occupiedId_returnsCollision {
57
+ FakePerfHandle *first = [[FakePerfHandle alloc] init];
58
+ XCTAssertTrue([self.registry put:@1 value:first error:nil]);
59
+
60
+ NSError *error = nil;
61
+ XCTAssertFalse([self.registry put:@1 value:[[FakePerfHandle alloc] init] error:&error]);
62
+ XCTAssertNotNil(error);
63
+ XCTAssertEqualObjects(error.domain, RNFBHandleMapErrorDomain);
64
+ XCTAssertEqual(error.code, RNFBHandleMapErrorCollision);
65
+ XCTAssertEqual(first, [self.registry get:@1]);
66
+ }
67
+
68
+ - (void)testPutOrDiscard_collision_dropsIncomingWithoutStop {
69
+ FakePerfHandle *first = [[FakePerfHandle alloc] init];
70
+ FakePerfHandle *duplicate = [[FakePerfHandle alloc] init];
71
+ XCTAssertTrue([self.registry put:@1 value:first error:nil]);
72
+ XCTAssertFalse([self.registry putOrDiscard:@1 value:duplicate]);
73
+ XCTAssertEqual(duplicate.stopCount, 0);
74
+ XCTAssertEqual(first.stopCount, 0);
75
+ XCTAssertEqual(first, [self.registry get:@1]);
76
+ }
77
+
78
+ - (void)testPutOrDiscard_storesWhenFree {
79
+ FakePerfHandle *handle = [[FakePerfHandle alloc] init];
80
+ XCTAssertTrue([self.registry putOrDiscard:@2 value:handle]);
81
+ XCTAssertEqual(handle, [self.registry get:@2]);
82
+ XCTAssertEqual(handle.stopCount, 0);
83
+ }
84
+
85
+ - (void)testPutReplacing_whenOccupied_returnsDisplaced {
86
+ FakePerfHandle *first = [[FakePerfHandle alloc] init];
87
+ FakePerfHandle *second = [[FakePerfHandle alloc] init];
88
+ XCTAssertTrue([self.registry put:@3 value:first error:nil]);
89
+ XCTAssertEqual(first, [self.registry putReplacing:@3 value:second]);
90
+ XCTAssertEqual(second, [self.registry get:@3]);
91
+ }
92
+
93
+ - (void)testPutReplacing_moduleCollisionPattern_stopsDisplacedOutsideLock {
94
+ FakePerfHandle *first = [[FakePerfHandle alloc] init];
95
+ FakePerfHandle *second = [[FakePerfHandle alloc] init];
96
+ XCTAssertTrue([self.registry put:@6 value:first error:nil]);
97
+ FakePerfHandle *displaced = [self.registry putReplacing:@6 value:second];
98
+ if (displaced != nil) {
99
+ [displaced stop];
100
+ }
101
+ XCTAssertEqual(first.stopCount, 1);
102
+ XCTAssertEqual(second.stopCount, 0);
103
+ XCTAssertEqual(second, [self.registry get:@6]);
104
+ }
105
+
106
+ - (void)testTakeAll_returnsSnapshotAndLeavesEmpty {
107
+ FakePerfHandle *a = [[FakePerfHandle alloc] init];
108
+ FakePerfHandle *b = [[FakePerfHandle alloc] init];
109
+ XCTAssertTrue([self.registry put:@4 value:a error:nil]);
110
+ XCTAssertTrue([self.registry put:@5 value:b error:nil]);
111
+ NSArray *remaining = [self.registry takeAll];
112
+ XCTAssertEqual(remaining.count, 2);
113
+ XCTAssertNil([self.registry get:@4]);
114
+ XCTAssertNil([self.registry get:@5]);
115
+ XCTAssertEqual(a.stopCount, 0);
116
+ XCTAssertEqual(b.stopCount, 0);
117
+ }
118
+
119
+ - (void)testGet_whenFree_isNil {
120
+ XCTAssertNil([self.registry get:@99]);
121
+ }
122
+
123
+ @end
@@ -0,0 +1,251 @@
1
+ // !$*UTF8*$!
2
+ {
3
+ archiveVersion = 1;
4
+ classes = {
5
+ };
6
+ objectVersion = 56;
7
+ objects = {
8
+
9
+ /* Begin PBXBuildFile section */
10
+ B9000000000000000000000A /* RNFBHandleMap.m in Sources */ = {isa = PBXBuildFile; fileRef = B90000000000000000000008 /* RNFBHandleMap.m */; };
11
+ B9000000000000000000000B /* RNFBPerfHandleRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = B90000000000000000000018 /* RNFBPerfHandleRegistry.m */; };
12
+ B9000000000000000000000C /* RNFBPerfHandleRegistryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B90000000000000000000009 /* RNFBPerfHandleRegistryTests.m */; };
13
+ B90000000000000000000015 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B90000000000000000000014 /* XCTest.framework */; };
14
+ /* End PBXBuildFile section */
15
+
16
+ /* Begin PBXFileReference section */
17
+ B90000000000000000000003 /* RNFBPerfUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNFBPerfUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
18
+ B90000000000000000000007 /* RNFBHandleMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBHandleMap.h; path = ../../../app/ios/RNFBApp/RNFBHandleMap.h; sourceTree = SOURCE_ROOT; };
19
+ B90000000000000000000008 /* RNFBHandleMap.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNFBHandleMap.m; path = ../../../app/ios/RNFBApp/RNFBHandleMap.m; sourceTree = SOURCE_ROOT; };
20
+ B90000000000000000000009 /* RNFBPerfHandleRegistryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNFBPerfHandleRegistryTests.m; sourceTree = "<group>"; };
21
+ B90000000000000000000016 /* RNFBPerfHandleRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBPerfHandleRegistry.h; path = ../RNFBPerf/RNFBPerfHandleRegistry.h; sourceTree = SOURCE_ROOT; };
22
+ B90000000000000000000018 /* RNFBPerfHandleRegistry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNFBPerfHandleRegistry.m; path = ../RNFBPerf/RNFBPerfHandleRegistry.m; sourceTree = SOURCE_ROOT; };
23
+ B90000000000000000000014 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
24
+ /* End PBXFileReference section */
25
+
26
+ /* Begin PBXFrameworksBuildPhase section */
27
+ B9000000000000000000000D /* Frameworks */ = {
28
+ isa = PBXFrameworksBuildPhase;
29
+ buildActionMask = 2147483647;
30
+ files = (
31
+ B90000000000000000000015 /* XCTest.framework in Frameworks */,
32
+ );
33
+ runOnlyForDeploymentPostprocessing = 0;
34
+ };
35
+ /* End PBXFrameworksBuildPhase section */
36
+
37
+ /* Begin PBXGroup section */
38
+ B90000000000000000000004 = {
39
+ isa = PBXGroup;
40
+ children = (
41
+ B90000000000000000000006 /* Sources */,
42
+ B90000000000000000000005 /* Products */,
43
+ );
44
+ sourceTree = "<group>";
45
+ };
46
+ B90000000000000000000005 /* Products */ = {
47
+ isa = PBXGroup;
48
+ children = (
49
+ B90000000000000000000003 /* RNFBPerfUnitTests.xctest */,
50
+ );
51
+ name = Products;
52
+ sourceTree = "<group>";
53
+ };
54
+ B90000000000000000000006 /* Sources */ = {
55
+ isa = PBXGroup;
56
+ children = (
57
+ B90000000000000000000007 /* RNFBHandleMap.h */,
58
+ B90000000000000000000008 /* RNFBHandleMap.m */,
59
+ B90000000000000000000016 /* RNFBPerfHandleRegistry.h */,
60
+ B90000000000000000000018 /* RNFBPerfHandleRegistry.m */,
61
+ B90000000000000000000009 /* RNFBPerfHandleRegistryTests.m */,
62
+ );
63
+ name = Sources;
64
+ sourceTree = "<group>";
65
+ };
66
+ /* End PBXGroup section */
67
+
68
+ /* Begin PBXNativeTarget section */
69
+ B90000000000000000000002 /* RNFBPerfUnitTests */ = {
70
+ isa = PBXNativeTarget;
71
+ buildConfigurationList = B90000000000000000000013 /* Build configuration list for PBXNativeTarget "RNFBPerfUnitTests" */;
72
+ buildPhases = (
73
+ B9000000000000000000000E /* Sources */,
74
+ B9000000000000000000000D /* Frameworks */,
75
+ );
76
+ buildRules = (
77
+ );
78
+ dependencies = (
79
+ );
80
+ name = RNFBPerfUnitTests;
81
+ productName = RNFBPerfUnitTests;
82
+ productReference = B90000000000000000000003 /* RNFBPerfUnitTests.xctest */;
83
+ productType = "com.apple.product-type.bundle.unit-test";
84
+ };
85
+ /* End PBXNativeTarget section */
86
+
87
+ /* Begin PBXProject section */
88
+ B90000000000000000000001 /* Project object */ = {
89
+ isa = PBXProject;
90
+ attributes = {
91
+ BuildIndependentTargetsInParallel = 1;
92
+ LastUpgradeCheck = 2600;
93
+ ORGANIZATIONNAME = Invertase;
94
+ TargetAttributes = {
95
+ B90000000000000000000002 = {
96
+ CreatedOnToolsVersion = 26.0;
97
+ };
98
+ };
99
+ };
100
+ buildConfigurationList = B90000000000000000000012 /* Build configuration list for PBXProject "RNFBPerfUnitTests" */;
101
+ compatibilityVersion = "Xcode 14.0";
102
+ developmentRegion = en;
103
+ hasScannedForEncodings = 0;
104
+ knownRegions = (
105
+ en,
106
+ Base,
107
+ );
108
+ mainGroup = B90000000000000000000004;
109
+ productRefGroup = B90000000000000000000005 /* Products */;
110
+ projectDirPath = "";
111
+ projectRoot = "";
112
+ targets = (
113
+ B90000000000000000000002 /* RNFBPerfUnitTests */,
114
+ );
115
+ };
116
+ /* End PBXProject section */
117
+
118
+ /* Begin PBXSourcesBuildPhase section */
119
+ B9000000000000000000000E /* Sources */ = {
120
+ isa = PBXSourcesBuildPhase;
121
+ buildActionMask = 2147483647;
122
+ files = (
123
+ B9000000000000000000000A /* RNFBHandleMap.m in Sources */,
124
+ B9000000000000000000000B /* RNFBPerfHandleRegistry.m in Sources */,
125
+ B9000000000000000000000C /* RNFBPerfHandleRegistryTests.m in Sources */,
126
+ );
127
+ runOnlyForDeploymentPostprocessing = 0;
128
+ };
129
+ /* End PBXSourcesBuildPhase section */
130
+
131
+ /* Begin XCBuildConfiguration section */
132
+ B9000000000000000000001A /* Debug */ = {
133
+ isa = XCBuildConfiguration;
134
+ buildSettings = {
135
+ ALWAYS_SEARCH_USER_PATHS = NO;
136
+ CLANG_ENABLE_MODULES = YES;
137
+ CLANG_ENABLE_OBJC_ARC = YES;
138
+ COPY_PHASE_STRIP = NO;
139
+ DEBUG_INFORMATION_FORMAT = dwarf;
140
+ ENABLE_TESTABILITY = YES;
141
+ GCC_C_LANGUAGE_STANDARD = gnu17;
142
+ GCC_DYNAMIC_NO_PIC = NO;
143
+ GCC_OPTIMIZATION_LEVEL = 0;
144
+ MACOSX_DEPLOYMENT_TARGET = 14.0;
145
+ ONLY_ACTIVE_ARCH = YES;
146
+ SDKROOT = macosx;
147
+ SUPPORTED_PLATFORMS = macosx;
148
+ };
149
+ name = Debug;
150
+ };
151
+ B9000000000000000000001B /* Release */ = {
152
+ isa = XCBuildConfiguration;
153
+ buildSettings = {
154
+ ALWAYS_SEARCH_USER_PATHS = NO;
155
+ CLANG_ENABLE_MODULES = YES;
156
+ CLANG_ENABLE_OBJC_ARC = YES;
157
+ COPY_PHASE_STRIP = YES;
158
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
159
+ GCC_C_LANGUAGE_STANDARD = gnu17;
160
+ MACOSX_DEPLOYMENT_TARGET = 14.0;
161
+ SDKROOT = macosx;
162
+ SUPPORTED_PLATFORMS = macosx;
163
+ };
164
+ name = Release;
165
+ };
166
+ B90000000000000000000010 /* Debug */ = {
167
+ isa = XCBuildConfiguration;
168
+ buildSettings = {
169
+ CLANG_ENABLE_CODE_COVERAGE = YES;
170
+ CODE_SIGNING_ALLOWED = NO;
171
+ CODE_SIGNING_REQUIRED = NO;
172
+ CODE_SIGN_IDENTITY = "-";
173
+ COMBINE_HIDPI_IMAGES = YES;
174
+ GENERATE_INFOPLIST_FILE = YES;
175
+ HEADER_SEARCH_PATHS = (
176
+ "$(SRCROOT)/../../../app/ios",
177
+ "$(SRCROOT)/../../../app/ios/RNFBApp",
178
+ "$(SRCROOT)/../RNFBPerf",
179
+ );
180
+ LD_RUNPATH_SEARCH_PATHS = (
181
+ "$(inherited)",
182
+ "@executable_path/../Frameworks",
183
+ "@loader_path/../Frameworks",
184
+ );
185
+ MACOSX_DEPLOYMENT_TARGET = 14.0;
186
+ OTHER_CFLAGS = (
187
+ "-fprofile-instr-generate",
188
+ "-fcoverage-mapping",
189
+ );
190
+ OTHER_LDFLAGS = (
191
+ "-fprofile-instr-generate",
192
+ );
193
+ PRODUCT_BUNDLE_IDENTIFIER = io.invertase.firebase.RNFBPerfUnitTests;
194
+ PRODUCT_NAME = "$(TARGET_NAME)";
195
+ SDKROOT = macosx;
196
+ SUPPORTED_PLATFORMS = macosx;
197
+ };
198
+ name = Debug;
199
+ };
200
+ B90000000000000000000011 /* Release */ = {
201
+ isa = XCBuildConfiguration;
202
+ buildSettings = {
203
+ CLANG_ENABLE_CODE_COVERAGE = YES;
204
+ CODE_SIGNING_ALLOWED = NO;
205
+ CODE_SIGNING_REQUIRED = NO;
206
+ CODE_SIGN_IDENTITY = "-";
207
+ COMBINE_HIDPI_IMAGES = YES;
208
+ GENERATE_INFOPLIST_FILE = YES;
209
+ HEADER_SEARCH_PATHS = (
210
+ "$(SRCROOT)/../../../app/ios",
211
+ "$(SRCROOT)/../../../app/ios/RNFBApp",
212
+ "$(SRCROOT)/../RNFBPerf",
213
+ );
214
+ LD_RUNPATH_SEARCH_PATHS = (
215
+ "$(inherited)",
216
+ "@executable_path/../Frameworks",
217
+ "@loader_path/../Frameworks",
218
+ );
219
+ MACOSX_DEPLOYMENT_TARGET = 14.0;
220
+ PRODUCT_BUNDLE_IDENTIFIER = io.invertase.firebase.RNFBPerfUnitTests;
221
+ PRODUCT_NAME = "$(TARGET_NAME)";
222
+ SDKROOT = macosx;
223
+ SUPPORTED_PLATFORMS = macosx;
224
+ };
225
+ name = Release;
226
+ };
227
+ /* End XCBuildConfiguration section */
228
+
229
+ /* Begin XCConfigurationList section */
230
+ B90000000000000000000012 /* Build configuration list for PBXProject "RNFBPerfUnitTests" */ = {
231
+ isa = XCConfigurationList;
232
+ buildConfigurations = (
233
+ B9000000000000000000001A /* Debug */,
234
+ B9000000000000000000001B /* Release */,
235
+ );
236
+ defaultConfigurationIsVisible = 0;
237
+ defaultConfigurationName = Debug;
238
+ };
239
+ B90000000000000000000013 /* Build configuration list for PBXNativeTarget "RNFBPerfUnitTests" */ = {
240
+ isa = XCConfigurationList;
241
+ buildConfigurations = (
242
+ B90000000000000000000010 /* Debug */,
243
+ B90000000000000000000011 /* Release */,
244
+ );
245
+ defaultConfigurationIsVisible = 0;
246
+ defaultConfigurationName = Debug;
247
+ };
248
+ /* End XCConfigurationList section */
249
+ };
250
+ rootObject = B90000000000000000000001 /* Project object */;
251
+ }
@@ -0,0 +1,69 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Scheme
3
+ LastUpgradeVersion = "2600"
4
+ version = "1.7">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "NO"
13
+ buildForArchiving = "NO"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "B90000000000000000000002"
18
+ BuildableName = "RNFBPerfUnitTests.xctest"
19
+ BlueprintName = "RNFBPerfUnitTests"
20
+ ReferencedContainer = "container:RNFBPerfUnitTests.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ buildConfiguration = "Debug"
27
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
+ shouldUseLaunchSchemeArgsEnv = "YES"
30
+ codeCoverageEnabled = "YES">
31
+ <Testables>
32
+ <TestableReference
33
+ skipped = "NO">
34
+ <BuildableReference
35
+ BuildableIdentifier = "primary"
36
+ BlueprintIdentifier = "B90000000000000000000002"
37
+ BuildableName = "RNFBPerfUnitTests.xctest"
38
+ BlueprintName = "RNFBPerfUnitTests"
39
+ ReferencedContainer = "container:RNFBPerfUnitTests.xcodeproj">
40
+ </BuildableReference>
41
+ </TestableReference>
42
+ </Testables>
43
+ </TestAction>
44
+ <LaunchAction
45
+ buildConfiguration = "Debug"
46
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
47
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
48
+ launchStyle = "0"
49
+ useCustomWorkingDirectory = "NO"
50
+ ignoresPersistentStateOnLaunch = "NO"
51
+ debugDocumentVersioning = "YES"
52
+ debugServiceExtension = "internal"
53
+ allowLocationSimulation = "YES">
54
+ </LaunchAction>
55
+ <ProfileAction
56
+ buildConfiguration = "Release"
57
+ shouldUseLaunchSchemeArgsEnv = "YES"
58
+ savedToolIdentifier = ""
59
+ useCustomWorkingDirectory = "NO"
60
+ debugDocumentVersioning = "YES">
61
+ </ProfileAction>
62
+ <AnalyzeAction
63
+ buildConfiguration = "Debug">
64
+ </AnalyzeAction>
65
+ <ArchiveAction
66
+ buildConfiguration = "Release"
67
+ revealArchiveInOrganizer = "YES">
68
+ </ArchiveAction>
69
+ </Scheme>
package/lib/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '26.3.2';
2
+ export const version = '26.4.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native-firebase/perf",
3
- "version": "26.3.2",
3
+ "version": "26.4.0",
4
4
  "author": "Invertase <oss@invertase.io> (http://invertase.io)",
5
5
  "description": "React Native Firebase - React Native Firebase provides native integration with Performance Monitoring to gain insight into key performance characteristics within your React Native application.",
6
6
  "main": "./dist/module/index.js",
@@ -30,6 +30,7 @@
30
30
  "android:codegen": "node ../../scripts/codegen-package.mjs perf android",
31
31
  "ios:codegen": "node ../../scripts/codegen-package.mjs perf ios"
32
32
  },
33
+ "homepage": "https://rnfirebase.io",
33
34
  "repository": {
34
35
  "type": "git",
35
36
  "url": "https://github.com/invertase/react-native-firebase",
@@ -48,11 +49,11 @@
48
49
  "performance monitoring"
49
50
  ],
50
51
  "peerDependencies": {
51
- "@react-native-firebase/app": "26.3.2",
52
+ "@react-native-firebase/app": "26.4.0",
52
53
  "expo": ">=47.0.0"
53
54
  },
54
55
  "devDependencies": {
55
- "@react-native-firebase/app": "26.3.2",
56
+ "@react-native-firebase/app": "26.4.0",
56
57
  "expo": "^55.0.18",
57
58
  "react-native-builder-bob": "^0.40.13"
58
59
  },
@@ -103,5 +104,5 @@
103
104
  "node_modules/",
104
105
  "dist/"
105
106
  ],
106
- "gitHead": "4ef21d038c5b372e67508265a5c3391a07c91fde"
107
+ "gitHead": "06701af5fdc19bae9f379567eadb29dfe81953c0"
107
108
  }