@debugbundle/sdk-react-native 1.1.0 → 1.2.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 ADDED
@@ -0,0 +1,35 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## Unreleased
6
+
7
+ ## 1.2.0 - 2026-07-29
8
+
9
+ - Preserve React Native SDK identity, original JavaScript error fields, service, correlation, context, probes, and mobile metadata through additive Android and Swift external-event APIs.
10
+ - Compose JavaScript request observations with native capture policy, remote probes, trigger tokens, queue/transport/redaction settings, headers, sampling, and probe configuration.
11
+ - Normalize integer-valued JavaScript numbers recursively at the Android bridge so native request capture policy and integer envelope fields retain their canonical types.
12
+ - Added the universal `beforeSend` hook, a committed npm lockfile, frozen installs, npm/pnpm/Yarn clean-package smokes, Android/iOS runtime delivery lanes, and Expo development-build verification.
13
+ - Coordinate native Android artifacts explicitly during clean Android and Expo builds so source validation never resolves an unrelated published native version.
14
+ - Resolve native modules through Metro-visible React Native imports, provide the generated iOS TurboModule implementation for New Architecture apps, preserve scalar context through an object-safe additive bridge, and retain merged app context on canonical request envelopes.
15
+ - Added a real RN 0.85 New Architecture iOS simulator smoke that verifies exception and failed-request delivery through the packed npm package, native Swift queue, and HTTP ingestion acknowledgement.
16
+ - Prepare the coordinated `1.2.0` source line with Android/Swift `1.2` requirements, enforce per-file TypeScript coverage, and block npm publication until clean Android and iOS apps compile against the published native artifacts.
17
+ - Add bare React Native 0.85 Android and Expo SDK 57 / React Native 0.86 Android end-to-end build verification, including consumer-safe Kotlin metadata validation.
18
+ - Add repository-local Android Java, Swift, and Objective-C++ wrapper tests and
19
+ enforce at least 80% line coverage for every handwritten native bridge
20
+ source in Make and CI.
21
+ - Preserve React Native 0.76 New Architecture codegen discovery by exporting
22
+ package metadata, accept both generated iOS header layouts, and give
23
+ unaccelerated Android runtime smokes enough time and diagnostics to
24
+ distinguish slow startup from bridge or ingestion failures.
25
+ - Preserve the legacy arbitrary-value Android `setContext` bridge through
26
+ React Native's New Architecture-compatible `Dynamic` type so module parsing
27
+ cannot crash the host process before initialization.
28
+
29
+ ## 1.1.0
30
+
31
+ - Added path-scoped immediate client-error promotion while retaining context-only handling for unpromoted client errors.
32
+
33
+ ## 1.0.0
34
+
35
+ - Declared the React Native Android/iOS package line stable.
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = "DebugBundleReactNative"
3
- s.version = "1.1.0"
3
+ s.version = "1.2.0"
4
4
  s.summary = "React Native wrapper for the DebugBundle mobile SDKs."
5
5
  s.license = { :type => "AGPL-3.0-only" }
6
6
  s.author = { "DebugBundle" => "support@debugbundle.com" }
@@ -11,5 +11,6 @@ Pod::Spec.new do |s|
11
11
  s.swift_version = "5.10"
12
12
 
13
13
  s.dependency "React-Core"
14
- s.dependency "DebugBundle", "~> 1.1"
14
+ install_modules_dependencies(s) if defined?(install_modules_dependencies)
15
+ s.dependency "DebugBundle", "~> 1.2"
15
16
  end
package/README.md CHANGED
@@ -16,6 +16,8 @@ Published implementation:
16
16
  - `fetch` and `XMLHttpRequest` instrumentation with target-scoped `X-DebugBundle-Trace-Id`.
17
17
  - JS-side bounded serialization and redaction before native queue persistence.
18
18
  - Android and iOS native wrappers that delegate queueing, config/status, request capture, crash/error capture, flushing, and probe trigger activation to the native SDK foundations.
19
+ - Repository-local Android Java, Swift, and Objective-C++ wrapper tests with an
20
+ enforced 80% line-coverage floor for every handwritten native bridge source.
19
21
  - Clean-install React Native app smoke coverage for Android and iOS, including New Architecture codegen/autolinking.
20
22
 
21
23
  ## Runtime Support
@@ -23,9 +25,9 @@ Published implementation:
23
25
  | Lane | Support |
24
26
  | --- | --- |
25
27
  | Minimum compatibility | React Native 0.76+, React 18.2+, iOS 15+, Android minSdk 23 |
26
- | Recommended production | Current stable React Native 0.85.x with Hermes and the New Architecture enabled where your app supports it |
28
+ | Recommended production | Current stable React Native 0.86.x with Hermes and the New Architecture enabled where your app supports it |
27
29
  | Installed-base compatibility | React Native 0.76 through current stable, including legacy bridge apps |
28
- | Rolling CI | TypeScript/package smoke, Android bridge compile on RN 0.76.9, 0.82.1, and 0.85.3, plus current-stable Android and iOS clean-app smokes |
30
+ | Rolling CI | TypeScript/package smoke, Android bridge compile on RN 0.76.9, 0.82.1, and 0.85.3, bare iOS compatibility/current-installed-base lanes, plus Expo SDK 57 / RN 0.86 Android and iOS development builds |
29
31
  | Expo | Expo development builds and prebuild; Expo Go is degraded because it cannot load custom native modules |
30
32
 
31
33
  JSC compatibility is best-effort where the selected React Native lane still supports it. Hermes is the primary tested JavaScript engine.
@@ -129,6 +131,14 @@ export function AppNavigation() {
129
131
 
130
132
  Expo development builds and prebuild are supported through the config plugin. Expo Go cannot load the native module, so the SDK reports degraded status and does not claim durable native queueing, native crash evidence, native device context, or remote-probe parity.
131
133
 
134
+ ## Verification
135
+
136
+ Run `make verify` for the TypeScript, package, and JavaScript coverage gates.
137
+ Run `make android-test` for the Android bridge unit/coverage gate and
138
+ `make ios-test` on macOS for the Swift and Objective-C++ bridge gates.
139
+ `make verify-native` combines the JavaScript and available platform-native
140
+ checks.
141
+
132
142
  ## Release
133
143
 
134
- The package publishes to npm from `v*` tags through GitHub Actions. Configure the repository secret `NPM_TOKEN`, make sure the tag matches `package.json` exactly, for example `v1.1.0`, and push the tag after the native Swift `DebugBundle` pod version referenced by `DebugBundleReactNative.podspec` is available to CocoaPods consumers.
144
+ The package publishes to npm from `v*` tags through GitHub Actions. Configure the repository secret `NPM_TOKEN`, make sure the tag matches `package.json` exactly, for example `v1.2.0`, and push the tag only after the exact Android and Swift native dependency line referenced by this package is available to Maven Central and CocoaPods consumers. The release workflow compiles clean apps against those published artifacts before npm publication.
@@ -1,5 +1,6 @@
1
1
  plugins {
2
2
  id "com.android.library"
3
+ id "jacoco"
3
4
  }
4
5
 
5
6
  def isReactNativeHostBuild = rootProject.name != "debugbundle-react-native"
@@ -10,6 +11,7 @@ if (isReactNativeHostBuild) {
10
11
  def hostKotlinVersion = rootProject.ext.has("kotlinVersion")
11
12
  ? rootProject.ext.get("kotlinVersion")
12
13
  : "2.1.20"
14
+ def debugBundleAndroidVersion = rootProject.findProperty("debugBundleAndroidVersion") ?: "1.2.0"
13
15
 
14
16
  android {
15
17
  namespace "com.debugbundle.reactnative"
@@ -23,15 +25,82 @@ android {
23
25
  sourceCompatibility JavaVersion.VERSION_17
24
26
  targetCompatibility JavaVersion.VERSION_17
25
27
  }
28
+
29
+ testOptions {
30
+ unitTests.returnDefaultValues = true
31
+ }
26
32
  }
27
33
 
28
34
  dependencies {
29
35
  compileOnly "com.facebook.react:react-android:${rootProject.findProperty("reactNativeVersion") ?: "0.85.3"}"
30
36
  implementation "org.jetbrains.kotlin:kotlin-stdlib:${hostKotlinVersion}"
31
- implementation platform("com.debugbundle:debugbundle-android-bom:1.1.0")
37
+ implementation platform("com.debugbundle:debugbundle-android-bom:${debugBundleAndroidVersion}")
32
38
  implementation("com.debugbundle:debugbundle-android") {
33
39
  exclude group: "org.jetbrains.kotlin", module: "kotlin-stdlib"
34
40
  exclude group: "org.jetbrains.kotlin", module: "kotlin-stdlib-jdk7"
35
41
  exclude group: "org.jetbrains.kotlin", module: "kotlin-stdlib-jdk8"
36
42
  }
43
+ testImplementation "com.facebook.react:react-android:${rootProject.findProperty("reactNativeVersion") ?: "0.85.3"}"
44
+ testImplementation "junit:junit:4.13.2"
45
+ testImplementation "org.mockito:mockito-core:5.14.2"
46
+ }
47
+
48
+ jacoco {
49
+ toolVersion = "0.8.13"
50
+ }
51
+
52
+ tasks.register("androidWrapperCoverage", JacocoReport) {
53
+ dependsOn "testDebugUnitTest"
54
+ executionData.from(fileTree(layout.buildDirectory) {
55
+ include "jacoco/testDebugUnitTest.exec"
56
+ include "outputs/unit_test_code_coverage/**/*.exec"
57
+ })
58
+ sourceDirectories.from(files("src/main/java"))
59
+ classDirectories.from(fileTree(layout.buildDirectory.dir("intermediates/javac/debug/compileDebugJavaWithJavac/classes")) {
60
+ exclude "**/BuildConfig.*"
61
+ exclude "**/R.class"
62
+ exclude '**/R$*.class'
63
+ })
64
+ reports {
65
+ xml.required = true
66
+ html.required = true
67
+ csv.required = false
68
+ }
69
+ }
70
+
71
+ tasks.register("verifyAndroidWrapperCoverage") {
72
+ dependsOn "androidWrapperCoverage"
73
+ doLast {
74
+ def report = file("${layout.buildDirectory.get()}/reports/jacoco/androidWrapperCoverage/androidWrapperCoverage.xml")
75
+ if (!report.isFile()) {
76
+ throw new GradleException("Android wrapper coverage report is missing: ${report}")
77
+ }
78
+ def sourceCoverage = [:]
79
+ def sourcePattern = ~/(?s)<sourcefile name="([^"]+)">.*?<counter type="LINE" missed="(\d+)" covered="(\d+)"\/><counter type="COMPLEXITY"/
80
+ (report.text =~ sourcePattern).each { match ->
81
+ sourceCoverage[match[1]] = [
82
+ missed: match[2].toInteger(),
83
+ covered: match[3].toInteger()
84
+ ]
85
+ }
86
+ fileTree("src/main/java") {
87
+ include "**/*.java"
88
+ }.files.sort().each { sourceFile ->
89
+ def coverage = sourceCoverage[sourceFile.name]
90
+ if (coverage == null) {
91
+ throw new GradleException("Android wrapper coverage did not include ${sourceFile.name}")
92
+ }
93
+ def ratio = coverage.covered / (coverage.covered + coverage.missed)
94
+ if (ratio < 0.80) {
95
+ throw new GradleException(
96
+ String.format(
97
+ "%s line coverage %.2f%% is below the required 80.00%%",
98
+ sourceFile.name,
99
+ ratio * 100
100
+ )
101
+ )
102
+ }
103
+ println String.format("%s line coverage: %.2f%%", sourceFile.name, ratio * 100)
104
+ }
105
+ }
37
106
  }