@dashx/react-native 1.5.0 → 1.5.1
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/README.md +1 -1
- package/ios/DashXReactNative.mm +7 -7
- package/ios/DashXReactNative.swift +15 -11
- package/package.json +13 -11
- package/.claude/settings.local.json +0 -7
- package/.claude/worktrees/autocapture-conventions-review-78f665/.gitattributes +0 -1
- package/.claude/worktrees/autocapture-conventions-review-78f665/.github/workflows/ci.yml +0 -67
- package/.claude/worktrees/autocapture-conventions-review-78f665/.gitignore +0 -49
- package/.claude/worktrees/autocapture-conventions-review-78f665/.nvmrc +0 -1
- package/.claude/worktrees/autocapture-conventions-review-78f665/CHANGELOG.md +0 -144
- package/.claude/worktrees/autocapture-conventions-review-78f665/CONTRIBUTING.md +0 -190
- package/.claude/worktrees/autocapture-conventions-review-78f665/DashXReactNative.podspec +0 -38
- package/.claude/worktrees/autocapture-conventions-review-78f665/LICENSE +0 -21
- package/.claude/worktrees/autocapture-conventions-review-78f665/README.md +0 -97
- package/.claude/worktrees/autocapture-conventions-review-78f665/__tests__/fallback.test.js +0 -72
- package/.claude/worktrees/autocapture-conventions-review-78f665/__tests__/index.test.js +0 -702
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/.gitignore +0 -10
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/.gradle/8.14.3/checksums/checksums.lock +0 -0
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/.gradle/8.14.3/fileChanges/last-build.bin +0 -0
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/.gradle/8.14.3/fileHashes/fileHashes.lock +0 -0
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/.gradle/8.14.3/gc.properties +0 -0
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/.gradle/buildOutputCleanup/cache.properties +0 -2
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/.gradle/vcs-1/gc.properties +0 -0
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/build/reports/problems/problems-report.html +0 -663
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/build.gradle +0 -121
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/gradle/wrapper/gradle-wrapper.properties +0 -6
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/gradle.properties +0 -1
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/gradlew +0 -185
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/gradlew.bat +0 -89
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/settings.gradle +0 -27
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/main/AndroidManifest.xml +0 -19
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/main/java/com/dashx/rn/sdk/DashXNotificationClickedListener.kt +0 -113
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/main/java/com/dashx/rn/sdk/DashXReactNativeFirebaseMessagingService.kt +0 -72
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/main/java/com/dashx/rn/sdk/DashXReactNativeModuleImpl.kt +0 -445
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/main/java/com/dashx/rn/sdk/MessageReceivedEventHolder.kt +0 -14
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/main/java/com/dashx/rn/sdk/ReactNativeLibraryInfoProvider.kt +0 -8
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/main/java/com/dashx/rn/sdk/util/Utils.kt +0 -208
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/main/resources/META-INF/services/com.dashx.android.DashXLibraryInfoProvider +0 -1
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/newarch/java/com/dashx/rn/sdk/DashXReactNativeModule.kt +0 -85
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/newarch/java/com/dashx/rn/sdk/DashXReactNativePackage.kt +0 -33
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/oldarch/java/com/dashx/rn/sdk/DashXReactNativeModule.kt +0 -106
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/oldarch/java/com/dashx/rn/sdk/DashXReactNativePackage.kt +0 -33
- package/.claude/worktrees/autocapture-conventions-review-78f665/android/src/test/java/com/dashx/rn/sdk/util/UtilsTest.kt +0 -305
- package/.claude/worktrees/autocapture-conventions-review-78f665/babel.config.js +0 -3
- package/.claude/worktrees/autocapture-conventions-review-78f665/index.d.ts +0 -321
- package/.claude/worktrees/autocapture-conventions-review-78f665/index.js +0 -300
- package/.claude/worktrees/autocapture-conventions-review-78f665/ios/DashXEventEmitter.swift +0 -15
- package/.claude/worktrees/autocapture-conventions-review-78f665/ios/DashXNotificationHandler.swift +0 -301
- package/.claude/worktrees/autocapture-conventions-review-78f665/ios/DashXReactNative-Bridging-Header.h +0 -3
- package/.claude/worktrees/autocapture-conventions-review-78f665/ios/DashXReactNative.mm +0 -77
- package/.claude/worktrees/autocapture-conventions-review-78f665/ios/DashXReactNative.swift +0 -244
- package/.claude/worktrees/autocapture-conventions-review-78f665/ios/DashXReactNative.xcodeproj/project.pbxproj +0 -280
- package/.claude/worktrees/autocapture-conventions-review-78f665/ios/DashXReactNative.xcworkspace/contents.xcworkspacedata +0 -7
- package/.claude/worktrees/autocapture-conventions-review-78f665/ios/DashXReactNative.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/.claude/worktrees/autocapture-conventions-review-78f665/package.json +0 -123
- package/.claude/worktrees/autocapture-conventions-review-78f665/scripts/generate-bridge-shim.js +0 -259
- package/.claude/worktrees/autocapture-conventions-review-78f665/src/NativeDashXReactNative.ts +0 -42
- package/.claude/worktrees/autocapture-conventions-review-78f665/yarn.lock +0 -6244
- package/.gitattributes +0 -1
- package/.github/workflows/ci.yml +0 -67
- package/.gitignore +0 -49
- package/.nvmrc +0 -1
- package/CHANGELOG.md +0 -144
- package/CONTRIBUTING.md +0 -190
- package/__tests__/fallback.test.js +0 -72
- package/__tests__/index.test.js +0 -702
- package/android/.gitignore +0 -10
- package/android/.gradle/8.14.3/checksums/checksums.lock +0 -0
- package/android/.gradle/8.14.3/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.14.3/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.14.3/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build/reports/problems/problems-report.html +0 -663
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +0 -6
- package/android/gradlew +0 -185
- package/android/gradlew.bat +0 -89
- package/android/src/test/java/com/dashx/rn/sdk/util/UtilsTest.kt +0 -305
- package/babel.config.js +0 -3
- package/scripts/generate-bridge-shim.js +0 -259
- package/yarn.lock +0 -6244
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<br />
|
|
3
|
-
<a href="https://dashx.com"><img src="https://raw.githubusercontent.com/dashxhq/
|
|
3
|
+
<a href="https://dashx.com"><img src="https://raw.githubusercontent.com/dashxhq/brand-book/master/assets/logo-black-text-color-icon@2x.png" alt="DashX" height="40" /></a>
|
|
4
4
|
<br />
|
|
5
5
|
<br />
|
|
6
6
|
<strong>Your All-in-One Product Stack</strong>
|
package/ios/DashXReactNative.mm
CHANGED
|
@@ -21,17 +21,17 @@ RCT_EXTERN_METHOD(configure:(NSDictionary *)options);
|
|
|
21
21
|
|
|
22
22
|
RCT_EXTERN_METHOD(identify:(NSDictionary *)options);
|
|
23
23
|
|
|
24
|
-
RCT_EXTERN_METHOD(setIdentity:(
|
|
24
|
+
RCT_EXTERN_METHOD(setIdentity:(id _Nullable)uid token:(id _Nullable)token);
|
|
25
25
|
|
|
26
26
|
RCT_EXTERN_METHOD(reset);
|
|
27
27
|
|
|
28
|
-
RCT_EXTERN_METHOD(track:(NSString *)event data:(
|
|
28
|
+
RCT_EXTERN_METHOD(track:(NSString *)event data:(id _Nullable)data);
|
|
29
29
|
|
|
30
|
-
RCT_EXTERN_METHOD(screen:(NSString *)screenName data:(
|
|
30
|
+
RCT_EXTERN_METHOD(screen:(NSString *)screenName data:(id _Nullable)data);
|
|
31
31
|
|
|
32
|
-
RCT_EXTERN_METHOD(fetchRecord:(NSString *)urn options:(
|
|
32
|
+
RCT_EXTERN_METHOD(fetchRecord:(NSString *)urn options:(id _Nullable)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
|
33
33
|
|
|
34
|
-
RCT_EXTERN_METHOD(searchRecords:(NSString *)resource options:(
|
|
34
|
+
RCT_EXTERN_METHOD(searchRecords:(NSString *)resource options:(id _Nullable)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
|
35
35
|
|
|
36
36
|
RCT_EXTERN_METHOD(fetchStoredPreferences:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
|
37
37
|
|
|
@@ -51,9 +51,9 @@ RCT_EXTERN_METHOD(enableLifecycleTracking);
|
|
|
51
51
|
|
|
52
52
|
RCT_EXTERN_METHOD(enableAdTracking);
|
|
53
53
|
|
|
54
|
-
RCT_EXTERN_METHOD(processURL:(NSString *)url source:(
|
|
54
|
+
RCT_EXTERN_METHOD(processURL:(NSString *)url source:(id _Nullable)source forwardToLinkHandler:(BOOL)forwardToLinkHandler);
|
|
55
55
|
|
|
56
|
-
RCT_EXTERN_METHOD(trackNotificationNavigation:(
|
|
56
|
+
RCT_EXTERN_METHOD(trackNotificationNavigation:(id _Nullable)action notificationId:(id _Nullable)notificationId);
|
|
57
57
|
|
|
58
58
|
RCT_EXTERN_METHOD(requestNotificationPermission:(BOOL)fallbackToSettings resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
|
59
59
|
|
|
@@ -40,9 +40,11 @@ class DashXReactNative: RCTEventEmitter {
|
|
|
40
40
|
try? DashX.identify(options: stringOptions)
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
// Nullable args are `id`: the new-arch interop runs typed ones through
|
|
44
|
+
// RCTConvert, which logs an NSNull conversion error for every null.
|
|
43
45
|
@objc(setIdentity:token:)
|
|
44
|
-
func setIdentity(_ uid:
|
|
45
|
-
DashX.setIdentity(uid: uid as String
|
|
46
|
+
func setIdentity(_ uid: Any?, _ token: Any?) {
|
|
47
|
+
DashX.setIdentity(uid: uid as? String, token: token as? String)
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
@objc
|
|
@@ -51,17 +53,18 @@ class DashXReactNative: RCTEventEmitter {
|
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
@objc(track:data:)
|
|
54
|
-
func track(_ event: String, _ data:
|
|
56
|
+
func track(_ event: String, _ data: Any?) {
|
|
55
57
|
DashX.track(event, withData: data as? [String: Any])
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
@objc(screen:data:)
|
|
59
|
-
func screen(_ screenName: String, _ data:
|
|
61
|
+
func screen(_ screenName: String, _ data: Any?) {
|
|
60
62
|
DashX.screen(screenName, withData: data as? [String: Any])
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
@objc(fetchRecord:options:resolve:reject:)
|
|
64
|
-
func fetchRecord(_ urn: String, options:
|
|
66
|
+
func fetchRecord(_ urn: String, options: Any?, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
67
|
+
let options = options as? NSDictionary
|
|
65
68
|
DashXClient.instance.fetchRecord(
|
|
66
69
|
urn: urn,
|
|
67
70
|
preview: options?["preview"] as? Bool,
|
|
@@ -78,7 +81,8 @@ class DashXReactNative: RCTEventEmitter {
|
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
@objc(searchRecords:options:resolve:reject:)
|
|
81
|
-
func searchRecords(_ resource: String, options:
|
|
84
|
+
func searchRecords(_ resource: String, options: Any?, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
85
|
+
let options = options as? NSDictionary
|
|
82
86
|
DashXClient.instance.searchRecords(
|
|
83
87
|
resource: resource,
|
|
84
88
|
filter: options?["filter"] as? [String: Any],
|
|
@@ -199,15 +203,15 @@ class DashXReactNative: RCTEventEmitter {
|
|
|
199
203
|
}
|
|
200
204
|
|
|
201
205
|
@objc(processURL:source:forwardToLinkHandler:)
|
|
202
|
-
func processURL(_ url: String, source:
|
|
206
|
+
func processURL(_ url: String, source: Any?, forwardToLinkHandler: Bool) {
|
|
203
207
|
guard let parsedURL = URL(string: url) else { return }
|
|
204
|
-
DashX.processURL(parsedURL, source: source as String
|
|
208
|
+
DashX.processURL(parsedURL, source: source as? String, forwardToLinkHandler: forwardToLinkHandler)
|
|
205
209
|
}
|
|
206
210
|
|
|
207
211
|
@objc(trackNotificationNavigation:notificationId:)
|
|
208
|
-
func trackNotificationNavigation(_ action:
|
|
212
|
+
func trackNotificationNavigation(_ action: Any?, notificationId: Any?) {
|
|
209
213
|
var navigationAction: NavigationAction? = nil
|
|
210
|
-
if let action = action, let type = action["type"] as? String {
|
|
214
|
+
if let action = action as? NSDictionary, let type = action["type"] as? String {
|
|
211
215
|
switch type {
|
|
212
216
|
case "deepLink":
|
|
213
217
|
if let urlString = action["url"] as? String, let url = URL(string: urlString) {
|
|
@@ -229,7 +233,7 @@ class DashXReactNative: RCTEventEmitter {
|
|
|
229
233
|
break
|
|
230
234
|
}
|
|
231
235
|
}
|
|
232
|
-
DashX.trackNotificationNavigation(navigationAction, notificationId: notificationId as String
|
|
236
|
+
DashX.trackNotificationNavigation(navigationAction, notificationId: notificationId as? String)
|
|
233
237
|
}
|
|
234
238
|
|
|
235
239
|
@objc(requestNotificationPermission:resolve:reject:)
|
package/package.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dashx/react-native",
|
|
3
3
|
"title": "DashX React Native",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.1",
|
|
5
5
|
"description": "DashX SDK for React Native",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"types": "index.d.ts",
|
|
8
8
|
"files": [
|
|
9
|
+
"android",
|
|
10
|
+
"DashXReactNative.podspec",
|
|
11
|
+
"index.js",
|
|
12
|
+
"index.d.ts",
|
|
13
|
+
"ios",
|
|
14
|
+
"src",
|
|
15
|
+
"README.md",
|
|
9
16
|
"!**/__fixtures__",
|
|
10
17
|
"!**/__mocks__",
|
|
11
18
|
"!**/__tests__",
|
|
@@ -15,15 +22,8 @@
|
|
|
15
22
|
"!android/gradlew.bat",
|
|
16
23
|
"!android/gradlew",
|
|
17
24
|
"!android/local.properties",
|
|
18
|
-
"!
|
|
19
|
-
"
|
|
20
|
-
"android",
|
|
21
|
-
"DashXReactNative.podspec",
|
|
22
|
-
"index.js",
|
|
23
|
-
"index.d.ts",
|
|
24
|
-
"ios",
|
|
25
|
-
"src",
|
|
26
|
-
"README.md"
|
|
25
|
+
"!android/src/test",
|
|
26
|
+
"!ios/build"
|
|
27
27
|
],
|
|
28
28
|
"codegenConfig": {
|
|
29
29
|
"name": "RNDashXReactNativeSpec",
|
|
@@ -37,7 +37,9 @@
|
|
|
37
37
|
"test": "jest",
|
|
38
38
|
"lint": "eslint index.js && yarn run check-bridge-shim",
|
|
39
39
|
"sync-bridge-shim": "node scripts/generate-bridge-shim.js",
|
|
40
|
-
"check-bridge-shim": "node scripts/generate-bridge-shim.js && git diff --exit-code ios/DashXReactNative.mm"
|
|
40
|
+
"check-bridge-shim": "node scripts/generate-bridge-shim.js && git diff --exit-code ios/DashXReactNative.mm",
|
|
41
|
+
"check-package": "node scripts/check-package.js",
|
|
42
|
+
"prepublishOnly": "node scripts/check-package.js"
|
|
41
43
|
},
|
|
42
44
|
"repository": {
|
|
43
45
|
"type": "git",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
*.pbxproj -text
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main, develop]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main, develop]
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
lint-and-test:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
steps:
|
|
13
|
-
- uses: actions/checkout@v4
|
|
14
|
-
|
|
15
|
-
- name: Setup Node.js
|
|
16
|
-
uses: actions/setup-node@v4
|
|
17
|
-
with:
|
|
18
|
-
node-version: 18
|
|
19
|
-
cache: yarn
|
|
20
|
-
|
|
21
|
-
- name: Install dependencies
|
|
22
|
-
run: yarn install --frozen-lockfile
|
|
23
|
-
|
|
24
|
-
- name: Lint
|
|
25
|
-
run: yarn lint
|
|
26
|
-
|
|
27
|
-
- name: Test
|
|
28
|
-
run: yarn test
|
|
29
|
-
|
|
30
|
-
# Android JVM unit tests for the bridge (see android/src/test). Runs
|
|
31
|
-
# standalone via the minimal `android/settings.gradle` + buildscript block
|
|
32
|
-
# added for this purpose — no consumer app checkout required. Scoped to
|
|
33
|
-
# PRs against `develop` and pushes to `main` per the team's release
|
|
34
|
-
# workflow (feature branches → develop, develop → main on release).
|
|
35
|
-
android-test:
|
|
36
|
-
runs-on: ubuntu-latest
|
|
37
|
-
if: >-
|
|
38
|
-
(github.event_name == 'push' && github.ref == 'refs/heads/main') ||
|
|
39
|
-
(github.event_name == 'pull_request' && github.base_ref == 'develop')
|
|
40
|
-
steps:
|
|
41
|
-
- uses: actions/checkout@v4
|
|
42
|
-
|
|
43
|
-
- name: Setup JDK 17
|
|
44
|
-
uses: actions/setup-java@v4
|
|
45
|
-
with:
|
|
46
|
-
distribution: temurin
|
|
47
|
-
java-version: 17
|
|
48
|
-
|
|
49
|
-
- name: Cache Gradle
|
|
50
|
-
uses: actions/cache@v4
|
|
51
|
-
with:
|
|
52
|
-
path: |
|
|
53
|
-
~/.gradle/caches
|
|
54
|
-
~/.gradle/wrapper
|
|
55
|
-
key: ${{ runner.os }}-gradle-${{ hashFiles('android/build.gradle', 'android/gradle/wrapper/gradle-wrapper.properties') }}
|
|
56
|
-
restore-keys: ${{ runner.os }}-gradle-
|
|
57
|
-
|
|
58
|
-
- name: Run Android unit tests
|
|
59
|
-
working-directory: android
|
|
60
|
-
run: ./gradlew :testDebugUnitTest --no-daemon
|
|
61
|
-
|
|
62
|
-
- name: Upload test report on failure
|
|
63
|
-
if: failure()
|
|
64
|
-
uses: actions/upload-artifact@v4
|
|
65
|
-
with:
|
|
66
|
-
name: android-test-report
|
|
67
|
-
path: android/build/reports/tests/testDebugUnitTest
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
# OSX
|
|
3
|
-
#
|
|
4
|
-
.DS_Store
|
|
5
|
-
|
|
6
|
-
# node.js
|
|
7
|
-
#
|
|
8
|
-
node_modules/
|
|
9
|
-
npm-debug.log
|
|
10
|
-
yarn-error.log
|
|
11
|
-
|
|
12
|
-
# Xcode
|
|
13
|
-
#
|
|
14
|
-
build/
|
|
15
|
-
*.pbxuser
|
|
16
|
-
!default.pbxuser
|
|
17
|
-
*.mode1v3
|
|
18
|
-
!default.mode1v3
|
|
19
|
-
*.mode2v3
|
|
20
|
-
!default.mode2v3
|
|
21
|
-
*.perspectivev3
|
|
22
|
-
!default.perspectivev3
|
|
23
|
-
xcuserdata
|
|
24
|
-
*.xccheckout
|
|
25
|
-
*.moved-aside
|
|
26
|
-
DerivedData
|
|
27
|
-
*.hmap
|
|
28
|
-
*.ipa
|
|
29
|
-
*.xcuserstate
|
|
30
|
-
project.xcworkspace
|
|
31
|
-
|
|
32
|
-
# Android/IntelliJ
|
|
33
|
-
#
|
|
34
|
-
build/
|
|
35
|
-
.idea
|
|
36
|
-
.gradle
|
|
37
|
-
# Kotlin 2.x incremental-compile cache (errors/, sessions/). Per-dev,
|
|
38
|
-
# regenerated on every compile.
|
|
39
|
-
.kotlin/
|
|
40
|
-
local.properties
|
|
41
|
-
*.iml
|
|
42
|
-
|
|
43
|
-
# BUCK
|
|
44
|
-
buck-out/
|
|
45
|
-
\.buckd/
|
|
46
|
-
*.keystore
|
|
47
|
-
|
|
48
|
-
# Cursor
|
|
49
|
-
.cursor
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
v24
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to `@dashx/react-native` are documented in this file. Format loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), versions follow [SemVer](https://semver.org/).
|
|
4
|
-
|
|
5
|
-
## [1.5.0] — 2026-10-28
|
|
6
|
-
|
|
7
|
-
### Required upgrade steps
|
|
8
|
-
|
|
9
|
-
1. **Bump the dashx-ios pod tag to 1.6.1 in your `ios/Podfile`**. `pod install` refuses the upgrade otherwise, because the podspec floor is now `>= 1.6.1`:
|
|
10
|
-
|
|
11
|
-
```ruby
|
|
12
|
-
pod 'DashX/SDK', :git => 'https://github.com/dashxhq/dashx-ios.git', :tag => '1.6.1'
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
### Breaking
|
|
16
|
-
|
|
17
|
-
- **Automatic events are renamed by the native SDKs**, now dashx-ios 1.6.1 and dashx-android 1.5.0. Screen views are `$screen` with the screen name in `$screen_name` (was `Screen Viewed` with `name`), `dx_deep_link_opened` is `Deep Link Opened` and `dx_notification_navigated` is `Push Notification Tapped`, with their data unchanged. Reports, flows or filters on the old names or the `name` key need updating. Lifecycle event names and keys are unchanged.
|
|
18
|
-
|
|
19
|
-
### Added
|
|
20
|
-
|
|
21
|
-
- **`DashX.enableLifecycleTracking()` on Android.** Previously iOS only (a no-op on Android). It now registers the dashx-android activity lifecycle callbacks with the application context. Call it after `configure`. With dashx-android 1.5.0 these are app-level: one launch event per cold start, `Application Opened` with `from_background` on return and `Application Backgrounded` on leaving, not one per Activity change.
|
|
22
|
-
- **`DashX.trackNavigation(navigationRef)`** for React Navigation. Sends a screen view for the current route once the `NavigationContainer` is ready, then one per change of the focused route's name, and returns a function that stops tracking. Screen views go through `DashX.screen`, which the native SDKs record as `$screen` with the route name in `$screen_name`. Route params are not sent. Works with any React Navigation version through its container ref, without a dependency on `@react-navigation/*`. Prefer it over native screen tracking: React Native screens are routes, not native view controllers or activities.
|
|
23
|
-
|
|
24
|
-
## [1.4.1] — 2026-05-06
|
|
25
|
-
|
|
26
|
-
### Required upgrade steps
|
|
27
|
-
|
|
28
|
-
1. **Bump the dashx-ios pod tag to 1.5.1 in your `ios/Podfile`** — `pod install` will refuse the upgrade otherwise (the podspec floor is now `>= 1.5.1`):
|
|
29
|
-
|
|
30
|
-
```ruby
|
|
31
|
-
pod 'DashX/SDK', :git => 'https://github.com/dashxhq/dashx-ios.git', :tag => '1.5.1'
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
The floor is required because earlier dashx-ios versions either fall back to silent-push on the backend (pre-1.3.0, throttled by iOS) or omit `.timeSensitive` from the authorization request (pre-1.5.1, causing `interruption-level: time-sensitive` payloads to silently downgrade and stay filterable by Focus / Reduce Interruptions / Scheduled Summary on iOS 18 / 26).
|
|
35
|
-
|
|
36
|
-
2. **Wire `fallbackToSettings: true` somewhere in your permission UI** to recover existing iOS users — fresh installs are auto-fixed by the upgrade, but users who already granted notification permission under the old SDK keep an `.authorized` state without the time-sensitive entitlement, and Apple's `requestAuthorization` is a one-shot grant that can't be silently upgraded. They have to flip the **Time Sensitive Notifications** toggle in iOS Settings themselves.
|
|
37
|
-
|
|
38
|
-
```js
|
|
39
|
-
// From a "Notifications acting up?" affordance, or as a one-time
|
|
40
|
-
// post-upgrade prompt:
|
|
41
|
-
await DashX.requestNotificationPermission({ fallbackToSettings: true });
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
When the user is already determined (granted or denied on iOS / permanently denied on Android), this opens the system notification settings page instead of firing a futile `requestAuthorization`. Without this step, your existing iOS users will keep experiencing the original "intermittent / second attempt works" symptom even after upgrading to 1.4.1.
|
|
45
|
-
|
|
46
|
-
### Migration
|
|
47
|
-
|
|
48
|
-
- **Consumers who subclass `DashXReactNativeModuleImpl`** and override `requestNotificationPermission(promise:)` need to update the override signature to `requestNotificationPermission(fallbackToSettings: Boolean, promise: Promise)`. Otherwise Kotlin's override resolution silently drops to the impl's version and your custom logic stops running. Same applies to anyone subclassing the new-arch / old-arch `DashXReactNativeModule` wrappers. Most consumers don't subclass these — flagged here for the few that do.
|
|
49
|
-
|
|
50
|
-
### Added
|
|
51
|
-
|
|
52
|
-
- **`DashX.requestNotificationPermission({ fallbackToSettings })`.** Optional flag, default `false`. When `true`, the SDK detects platform-specific dead-ends and opens the system notification-settings page instead of firing a futile prompt:
|
|
53
|
-
- **iOS** — already granted or denied (iOS no-ops `requestAuthorization` in that state).
|
|
54
|
-
- **Android** — `POST_NOTIFICATIONS` permanently denied (Android 13+, two-strikes rule). `requestPermissions()` auto-resolves DENIED without UI in that state.
|
|
55
|
-
|
|
56
|
-
Existing call sites (`DashX.requestNotificationPermission()` with no arguments) compile and behave unchanged.
|
|
57
|
-
|
|
58
|
-
### Fixed
|
|
59
|
-
|
|
60
|
-
- **Foreground push duplicate-display race in `DashXNotificationHandler.handleRemoteNotification`.** Now short-circuits when the payload already carries `aps.alert`, letting iOS render the notification natively via NSE / `willPresent` instead of racing a duplicate `UNUserNotificationCenter.add(...)` against it. Without the short-circuit the local re-add could clobber the NSE-attached image or briefly flicker on screen.
|
|
61
|
-
- **Suspension race in the image-attached reconstruction path.** The `fetchCompletionHandler` now fires only after the async image download and the local `add()` both complete, with a 25-second budget under iOS's background-push limit. Previously the handler fired immediately while the download was still in flight, letting iOS suspend the process before the notification actually displayed.
|
|
62
|
-
|
|
63
|
-
## [1.4.0] — 2026-04-27
|
|
64
|
-
|
|
65
|
-
### Changed
|
|
66
|
-
|
|
67
|
-
- **`DashX.unsubscribe()` now returns `Promise<{ success: boolean }>`** (was `void`). Matches `@dashx/browser`'s shape exactly — apps using a Metro `.web.ts` resolver can now share a single typed callsite across web and native.
|
|
68
|
-
|
|
69
|
-
**Migration**
|
|
70
|
-
|
|
71
|
-
Most existing call sites continue to work unchanged:
|
|
72
|
-
|
|
73
|
-
```ts
|
|
74
|
-
DashX.unsubscribe() // ✓ fire-and-forget still works
|
|
75
|
-
await DashX.unsubscribe() // ✓ still works (return value just unused)
|
|
76
|
-
const { success } = await DashX.unsubscribe() // new capability
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Two situations to watch for after upgrading:
|
|
80
|
-
|
|
81
|
-
- **Unhandled-rejection warnings.** Previously the native module surfaced errors only in its own logs; the JS API was silent. Now JS-side promise rejections fire on SDK-state problems (Firebase Messaging dependency missing, `configure()` not yet called) and transport failures (Firebase `deleteToken` failure, GraphQL / network errors). If you never caught errors before because there was nothing to catch, a fire-and-forget `DashX.unsubscribe()` may now surface "Possible Unhandled Promise Rejection" warnings in your console. Wrap with `.catch(...)` or `try / await` if those warnings are noisy.
|
|
82
|
-
- **TypeScript `: void` annotations.** `const x: void = DashX.unsubscribe()` no longer compiles. Vanishingly rare in practice but worth a grep.
|
|
83
|
-
|
|
84
|
-
**What the resolved value means**
|
|
85
|
-
|
|
86
|
-
- **`success: true`** — backend found and unsubscribed a matching contact.
|
|
87
|
-
- **`success: false`** — non-error outcome meaning "no matching contact found"; typically the anonymous UID rotated since subscribe, the FCM token is stale, the contact is already unsubscribed, or `unsubscribe()` was called on a device that never subscribed in this session. The device ends up unsubscribed in either case; the boolean is useful for diagnostics and analytics.
|
|
88
|
-
- **Promise rejection** — distinct from `success: false` so callers can branch on SDK-misuse vs legitimate no-match.
|
|
89
|
-
|
|
90
|
-
- **Native pin bumps to pick up the underlying schema change:**
|
|
91
|
-
- `android/build.gradle` → `com.dashx:dashx-android` `1.2.7` → `1.2.8`. The bridge now passes `onSuccess` / `onError(DashXError)` callbacks to the native `DashX.unsubscribe(...)` and resolves/rejects the JS promise accordingly.
|
|
92
|
-
- iOS pod consumers should bump `pod 'DashX/SDK'` to `:tag => '1.5.0'` in their Podfile. The bridge now calls `DashX.unsubscribe { result in ... }` and resolves/rejects the JS promise from the `Result<Bool, Error>` completion.
|
|
93
|
-
|
|
94
|
-
## [1.3.2] — 2026-04-22
|
|
95
|
-
|
|
96
|
-
### Added
|
|
97
|
-
- **`DashX.onPushNotificationReceived(callback)`** — new name for registering a foreground push listener. Same signature, same subscription shape; matches the `@dashx/browser` API so cross-platform apps using a Metro `.web.ts` wrapper can share the callsite.
|
|
98
|
-
|
|
99
|
-
### Deprecated
|
|
100
|
-
- **`DashX.onMessageReceived(callback)`** is now a deprecated alias of `onPushNotificationReceived` and logs a one-time `console.warn` on first call. The name leaked up from Android's Firebase `FirebaseMessagingService.onMessageReceived` override and was ambiguous in the DashX domain ("message" overloaded with `trackMessage` and in-app notifications). Scheduled for removal in the next major version.
|
|
101
|
-
|
|
102
|
-
## [1.3.1] — 2026-04-21
|
|
103
|
-
|
|
104
|
-
### Added
|
|
105
|
-
- **`DashX.onNotificationClicked` now fires on Android.** Previously only wired on iOS — the Android bridge didn't register a `DashXNotificationListener` with the SDK, so JS listeners never received tap events. The bridge now registers a listener in `DashXReactNativeModuleImpl.initialize()` and emits a `notificationClicked` event matching the iOS shape: `{ notification, action, actionIdentifier }`. `actionIdentifier` is the tapped button's identifier (body tap → empty string, matching iOS's always-a-string contract).
|
|
106
|
-
- Android JVM unit tests for the kotlinx-serialization conversion helpers (`Utils.kt`) — 16 tests covering all primitive types, nested objects/arrays, null handling, round-trips, and regression cases for the two pre-migration crash paths. Runs as a dedicated `android-test` CI job on PRs to `develop` and pushes to `main`.
|
|
107
|
-
|
|
108
|
-
### Changed
|
|
109
|
-
- **Android JSON handling consolidated on kotlinx-serialization.** Removed the Gson dependency and the `org.json`-shaped helpers (`MapUtil.java`, `ArrayUtil.java`), rewrote `Utils.kt` to use kotlinx `JsonObject` / `JsonArray` end-to-end. Matches how dashx-android itself serializes (its Apollo scalar mapping is `kotlinx.serialization.json.JsonObject`), eliminates the string round-trips the previous cross-library code was doing, and removes a class of bugs where three JSON libraries coexisted. Internal helper signatures changed (`convertMapToJson` now returns `JsonObject?`, `convertJsonToMap` now takes `JsonObject?`); consumer JS API is unchanged.
|
|
110
|
-
- `android/build.gradle` dep on `com.dashx:dashx-android` bumped `1.2.6` → `1.2.7` to receive the new 3-arg `onNotificationClicked(payload, action, actionIdentifier)` listener overload.
|
|
111
|
-
|
|
112
|
-
### Fixed
|
|
113
|
-
- `uploadAsset` / `fetchAsset` on Android previously failed to compile against `@dashx/react-native` due to a type mismatch in the TurboModule-migration callsite (`org.json.JSONObject` passed to a Gson `JsonObject`-typed helper, introduced in 1.2.0's TurboModule PR and never caught because no Android consumer had built the bridge since). Fixed by the Gson → kotlinx migration described above.
|
|
114
|
-
|
|
115
|
-
## [1.3.0] — 2026-04-20
|
|
116
|
-
|
|
117
|
-
### Breaking
|
|
118
|
-
- **`DashX` pod → `DashX/SDK`.** The podspec now depends on the `DashX/SDK` subspec of [dashx-ios 1.4.0+](https://github.com/dashxhq/dashx-ios) with no version constraint. Consumers must update their Podfile:
|
|
119
|
-
```ruby
|
|
120
|
-
# before
|
|
121
|
-
pod 'DashX', :git => 'https://github.com/dashxhq/dashx-ios.git', :tag => '1.1.9'
|
|
122
|
-
|
|
123
|
-
# after
|
|
124
|
-
pod 'DashX/SDK', :git => 'https://github.com/dashxhq/dashx-ios.git', :tag => '1.4.0'
|
|
125
|
-
```
|
|
126
|
-
- **`FirebaseMessaging` is now a hard dependency.** Previously the bridge guarded Firebase usage with `#if canImport(FirebaseMessaging)`, but `canImport` doesn't see consumer-Podfile pods at this pod's compile time, so the guard silently elided every FCM code path — push registration stopped working on fresh installs. Consumers must enable modular headers in their Podfile:
|
|
127
|
-
```ruby
|
|
128
|
-
use_modular_headers!
|
|
129
|
-
# or, per-pod:
|
|
130
|
-
pod 'FirebaseMessaging', :modular_headers => true
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Added
|
|
134
|
-
- `DashX.onNotificationClicked(callback)` — fires when the user taps a DashX notification or one of its action buttons. Callback receives `{ notification, action, actionIdentifier }` where `action` is a resolved `NavigationAction` (`deepLink` / `screen` / `richLanding` / `clickAction`) or `null`.
|
|
135
|
-
- `DashXNotificationResponseResult.navigationAction` — new Swift-only field on the helper result type returned by `DashXNotificationHandler.handleNotificationResponse(_:)`.
|
|
136
|
-
- `NotificationClickedEvent` exported from `index.d.ts`.
|
|
137
|
-
|
|
138
|
-
### Fixed
|
|
139
|
-
- **iOS dev builds silently failing to receive pushes.** `Messaging.messaging().setAPNSToken(_, type: .unknown)` sometimes mis-tagged the APNs environment on dev-signed binaries, producing an FCM token whose pushes 410'd at Apple. The bridge now forces `.sandbox` in `DEBUG` configurations and `.prod` otherwise.
|
|
140
|
-
- **`DashX.setIdentity(uid, token)` now passes `null` / `""` / `undefined` through to the native SDK unchanged** (apart from normalizing `undefined → null`, since the RN bridge can't carry `undefined`). Previously the JS wrapper threw on `null` / `""` / `undefined` for `uid`, contradicting the nullable signatures on iOS (`NSString?`) and Android (`String?`). TypeScript signature updated: `setIdentity(uid: string | null, token?: string | null): void`.
|
|
141
|
-
|
|
142
|
-
## [1.2.0] — 2026-04-16
|
|
143
|
-
|
|
144
|
-
Previous release — see git log.
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
# Contributing to @dashx/react-native
|
|
2
|
-
|
|
3
|
-
## Prerequisites
|
|
4
|
-
|
|
5
|
-
- Node.js >= 16
|
|
6
|
-
- Yarn
|
|
7
|
-
- Xcode (for iOS)
|
|
8
|
-
- Android Studio with JDK 17 (for Android)
|
|
9
|
-
- CocoaPods (`gem install cocoapods`)
|
|
10
|
-
|
|
11
|
-
## Getting Started
|
|
12
|
-
|
|
13
|
-
1. Clone the repository:
|
|
14
|
-
|
|
15
|
-
```sh
|
|
16
|
-
git clone https://github.com/dashxhq/dashx-react-native.git
|
|
17
|
-
cd dashx-react-native
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
2. Install dependencies:
|
|
21
|
-
|
|
22
|
-
```sh
|
|
23
|
-
yarn install
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
3. Run tests:
|
|
27
|
-
|
|
28
|
-
```sh
|
|
29
|
-
yarn test
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
4. Run lint:
|
|
33
|
-
|
|
34
|
-
```sh
|
|
35
|
-
yarn lint
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Building the SDK Locally
|
|
39
|
-
|
|
40
|
-
### Android
|
|
41
|
-
|
|
42
|
-
The Android bridge lives in `android/` and is a Gradle library module that is built as part of a React Native app — it cannot be built standalone because it depends on the React Native Gradle plugin and Android SDK provided by the host app.
|
|
43
|
-
|
|
44
|
-
To build and test locally, use a React Native demo app (e.g. `dashx-demo-react-native`):
|
|
45
|
-
|
|
46
|
-
1. In the demo app's `package.json`, point to your local SDK checkout:
|
|
47
|
-
|
|
48
|
-
```json
|
|
49
|
-
"dependencies": {
|
|
50
|
-
"@dashx/react-native": "file:../dashx-react-native"
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
2. Install and build:
|
|
55
|
-
|
|
56
|
-
```sh
|
|
57
|
-
cd dashx-demo-react-native
|
|
58
|
-
yarn install
|
|
59
|
-
cd android
|
|
60
|
-
./gradlew assembleDebug
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
3. **To test with a local `dashx-android` SDK build**, publish it to local Maven and add `mavenLocal()` to the demo app's `android/build.gradle` repositories:
|
|
64
|
-
|
|
65
|
-
```sh
|
|
66
|
-
# In dashx-android:
|
|
67
|
-
./gradlew publishToMavenLocal
|
|
68
|
-
|
|
69
|
-
# In dashx-react-native/android/build.gradle, add:
|
|
70
|
-
repositories {
|
|
71
|
-
mavenLocal()
|
|
72
|
-
// ...
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### iOS
|
|
77
|
-
|
|
78
|
-
The iOS bridge lives in `ios/` and is distributed as a CocoaPod (`DashXReactNative.podspec`). Like Android, it is built as part of a React Native app's Xcode workspace.
|
|
79
|
-
|
|
80
|
-
To build and test locally, use a React Native demo app (e.g. `dashx-demo-react-native`):
|
|
81
|
-
|
|
82
|
-
1. In the demo app's `package.json`, point to your local SDK checkout:
|
|
83
|
-
|
|
84
|
-
```json
|
|
85
|
-
"dependencies": {
|
|
86
|
-
"@dashx/react-native": "file:../dashx-react-native"
|
|
87
|
-
}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
2. Install dependencies and pods:
|
|
91
|
-
|
|
92
|
-
```sh
|
|
93
|
-
cd dashx-demo-react-native
|
|
94
|
-
yarn install
|
|
95
|
-
cd ios
|
|
96
|
-
pod install
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
3. Build from Xcode by opening the `.xcworkspace`, or from the command line:
|
|
100
|
-
|
|
101
|
-
```sh
|
|
102
|
-
xcodebuild -workspace ios/DashXDemoReactNative.xcworkspace \
|
|
103
|
-
-scheme DashXDemoReactNative \
|
|
104
|
-
-destination 'generic/platform=iOS Simulator' \
|
|
105
|
-
build
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
4. **To test with a local `dashx-ios` SDK build**, add a path override in the demo app's `Podfile`:
|
|
109
|
-
|
|
110
|
-
```ruby
|
|
111
|
-
pod 'DashX', :path => '../../dashx-ios'
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Then re-run `pod install`.
|
|
115
|
-
|
|
116
|
-
## Project Structure
|
|
117
|
-
|
|
118
|
-
```
|
|
119
|
-
dashx-react-native/
|
|
120
|
-
index.js # JS bridge — public API surface
|
|
121
|
-
index.d.ts # TypeScript type definitions
|
|
122
|
-
android/
|
|
123
|
-
src/main/java/com/dashx/rn/sdk/
|
|
124
|
-
DashXReactNativeModule.kt # Android native module
|
|
125
|
-
DashXReactNativePackage.kt # Package registration
|
|
126
|
-
DashXReactNativeFirebaseMessagingService.kt # FCM service
|
|
127
|
-
util/ # Bridge conversion utilities
|
|
128
|
-
build.gradle # Android build config
|
|
129
|
-
ios/
|
|
130
|
-
DashXReactNative.swift # iOS native module — SOURCE OF TRUTH for bridge methods
|
|
131
|
-
DashXReactNative.mm # Obj-C++ bridge exports — AUTO-GENERATED, see below
|
|
132
|
-
DashXEventEmitter.swift # Event emitter for push notifications
|
|
133
|
-
DashXRCTAppDelegate.swift # AppDelegate with Firebase/push handling
|
|
134
|
-
scripts/
|
|
135
|
-
generate-bridge-shim.js # Regenerates DashXReactNative.mm from the Swift @objc decls
|
|
136
|
-
DashXReactNative.podspec # CocoaPods spec
|
|
137
|
-
__tests__/ # Jest tests
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
## iOS bridge: editing methods
|
|
141
|
-
|
|
142
|
-
`ios/DashXReactNative.mm` is **auto-generated** from `ios/DashXReactNative.swift`.
|
|
143
|
-
Don't hand-edit it — your changes will be overwritten on the next regen, and CI
|
|
144
|
-
will fail anyway because the committed `.mm` won't match what the script
|
|
145
|
-
produces.
|
|
146
|
-
|
|
147
|
-
Workflow when adding or changing a bridged method:
|
|
148
|
-
|
|
149
|
-
1. Edit `ios/DashXReactNative.swift`. Each bridged method needs an `@objc`
|
|
150
|
-
decoration. Multi-arg methods use the explicit form
|
|
151
|
-
`@objc(methodName:label1:label2:)`; zero-arg methods use bare `@objc`.
|
|
152
|
-
2. Run the regen:
|
|
153
|
-
```sh
|
|
154
|
-
yarn sync-bridge-shim
|
|
155
|
-
```
|
|
156
|
-
3. Commit both the Swift change AND the regenerated `ios/DashXReactNative.mm`
|
|
157
|
-
in the same PR.
|
|
158
|
-
|
|
159
|
-
CI verification: `yarn lint` chains `yarn check-bridge-shim`, which re-runs
|
|
160
|
-
the generator and fails on a non-empty `git diff` against the committed
|
|
161
|
-
`.mm`. So a forgotten `sync-bridge-shim` step is caught at PR time, not in
|
|
162
|
-
production.
|
|
163
|
-
|
|
164
|
-
Why the `.mm` exists at all: React Native's iOS bridge requires every Swift
|
|
165
|
-
method to be declared in BOTH the Swift `@objc` form (for runtime dispatch)
|
|
166
|
-
AND in `RCT_EXTERN_METHOD(...)` form in an Obj-C++ shim (for old-arch
|
|
167
|
-
consumers' bridge module registration + new-arch compile-time selector
|
|
168
|
-
verification). The script makes the Swift declarations the single source of
|
|
169
|
-
truth and emits the matching shim mechanically.
|
|
170
|
-
|
|
171
|
-
If the script ever fails with `unknown Swift parameter type "..."`, add a
|
|
172
|
-
mapping for that type in `scripts/generate-bridge-shim.js`'s
|
|
173
|
-
`SWIFT_TO_OBJC` table (one line, then re-run).
|
|
174
|
-
|
|
175
|
-
## Running Tests
|
|
176
|
-
|
|
177
|
-
```sh
|
|
178
|
-
yarn test
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
Tests mock the React Native native modules and verify the JS bridge layer: input validation, native method delegation, promise handling, and event listener registration.
|
|
182
|
-
|
|
183
|
-
## Publishing
|
|
184
|
-
|
|
185
|
-
Use `yarn publish` to bump the version and release to npm:
|
|
186
|
-
|
|
187
|
-
```sh
|
|
188
|
-
yarn publish
|
|
189
|
-
git push origin main
|
|
190
|
-
```
|