@teardown/dev-client 2.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/android/build.gradle.kts +34 -0
  2. package/android/react-native.config.js +10 -0
  3. package/android/src/main/AndroidManifest.xml +7 -0
  4. package/android/src/main/java/com/teardown/devclient/DevSettingsModule.kt +130 -0
  5. package/android/src/main/java/com/teardown/devclient/ShakeDetectorModule.kt +118 -0
  6. package/android/src/main/java/com/teardown/devclient/TeardownDevClientPackage.kt +23 -0
  7. package/ios/TeardownDevClient/DevSettingsModule.swift +135 -0
  8. package/ios/TeardownDevClient/ShakeDetector.swift +102 -0
  9. package/ios/TeardownDevClient/TeardownDevClient.h +14 -0
  10. package/ios/TeardownDevClient/TeardownDevClient.mm +42 -0
  11. package/ios/TeardownDevClient.podspec +23 -0
  12. package/package.json +56 -0
  13. package/src/components/dev-menu/dev-menu.tsx +254 -0
  14. package/src/components/dev-menu/index.ts +5 -0
  15. package/src/components/error-overlay/error-overlay.tsx +256 -0
  16. package/src/components/error-overlay/index.ts +5 -0
  17. package/src/components/index.ts +7 -0
  18. package/src/components/splash-screen/index.ts +5 -0
  19. package/src/components/splash-screen/splash-screen.tsx +99 -0
  20. package/src/dev-client-provider.tsx +204 -0
  21. package/src/hooks/index.ts +24 -0
  22. package/src/hooks/use-bundler-status.ts +139 -0
  23. package/src/hooks/use-dev-menu.ts +306 -0
  24. package/src/hooks/use-splash-screen.ts +177 -0
  25. package/src/index.ts +77 -0
  26. package/src/native/dev-settings.ts +132 -0
  27. package/src/native/index.ts +16 -0
  28. package/src/native/shake-detector.ts +105 -0
  29. package/src/types.ts +235 -0
  30. package/src/utils/bundler-url.ts +103 -0
  31. package/src/utils/index.ts +19 -0
  32. package/src/utils/platform.ts +64 -0
@@ -0,0 +1,34 @@
1
+ plugins {
2
+ id("com.android.library")
3
+ id("kotlin-android")
4
+ }
5
+
6
+ android {
7
+ namespace = "com.teardown.devclient"
8
+ compileSdk = 34
9
+
10
+ defaultConfig {
11
+ minSdk = 23
12
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
13
+ }
14
+
15
+ buildTypes {
16
+ release {
17
+ isMinifyEnabled = false
18
+ }
19
+ }
20
+
21
+ compileOptions {
22
+ sourceCompatibility = JavaVersion.VERSION_17
23
+ targetCompatibility = JavaVersion.VERSION_17
24
+ }
25
+
26
+ kotlinOptions {
27
+ jvmTarget = "17"
28
+ }
29
+ }
30
+
31
+ dependencies {
32
+ implementation("com.facebook.react:react-android")
33
+ implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.22")
34
+ }
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ android: {
5
+ packageImportPath: 'import com.teardown.devclient.TeardownDevClientPackage;',
6
+ packageInstance: 'new TeardownDevClientPackage()',
7
+ },
8
+ },
9
+ },
10
+ };
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="com.teardown.devclient">
4
+
5
+ <!-- No permissions required for dev client functionality -->
6
+
7
+ </manifest>
@@ -0,0 +1,130 @@
1
+ package com.teardown.devclient
2
+
3
+ import com.facebook.react.bridge.*
4
+ import com.facebook.react.devsupport.DevInternalSettings
5
+ import com.facebook.react.modules.core.DeviceEventManagerModule
6
+
7
+ /**
8
+ * Native module for controlling React Native dev settings
9
+ */
10
+ class DevSettingsModule(private val reactContext: ReactApplicationContext) :
11
+ ReactContextBaseJavaModule(reactContext) {
12
+
13
+ override fun getName(): String = "TeardownDevSettings"
14
+
15
+ /**
16
+ * Reload the JavaScript bundle
17
+ */
18
+ @ReactMethod
19
+ fun reload() {
20
+ reactApplicationContext.runOnUiQueueThread {
21
+ try {
22
+ getDevSupportManager()?.handleReloadJS()
23
+ } catch (e: Exception) {
24
+ // Ignore errors if dev support is not available
25
+ }
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Open the debugger
31
+ */
32
+ @ReactMethod
33
+ fun openDebugger() {
34
+ reactApplicationContext.runOnUiQueueThread {
35
+ try {
36
+ getDevSupportManager()?.showDevOptionsDialog()
37
+ } catch (e: Exception) {
38
+ // Ignore errors if dev support is not available
39
+ }
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Toggle element inspector overlay
45
+ */
46
+ @ReactMethod
47
+ fun toggleElementInspector() {
48
+ reactApplicationContext.runOnUiQueueThread {
49
+ try {
50
+ getDevSupportManager()?.toggleElementInspector()
51
+ } catch (e: Exception) {
52
+ // Ignore errors if dev support is not available
53
+ }
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Set hot loading enabled state
59
+ */
60
+ @ReactMethod
61
+ fun setHotLoadingEnabled(enabled: Boolean) {
62
+ try {
63
+ getDevSettings()?.isHotModuleReplacementEnabled = enabled
64
+ } catch (e: Exception) {
65
+ // Ignore errors
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Set fast refresh enabled state
71
+ */
72
+ @ReactMethod
73
+ fun setFastRefreshEnabled(enabled: Boolean) {
74
+ // Fast refresh uses the same setting as hot loading
75
+ setHotLoadingEnabled(enabled)
76
+ }
77
+
78
+ /**
79
+ * Get current dev settings
80
+ */
81
+ @ReactMethod
82
+ fun getDevSettings(promise: Promise) {
83
+ try {
84
+ val devSettings = getDevSettings()
85
+ val result = Arguments.createMap().apply {
86
+ putBoolean("isDebuggingRemotely", devSettings?.isRemoteJSDebugEnabled ?: false)
87
+ putBoolean("isElementInspectorShown", false) // Not easily accessible on Android
88
+ putBoolean("isHotLoadingEnabled", devSettings?.isHotModuleReplacementEnabled ?: false)
89
+ putBoolean("isFastRefreshEnabled", devSettings?.isHotModuleReplacementEnabled ?: false)
90
+ putBoolean("isPerfMonitorShown", devSettings?.isFpsDebugEnabled ?: false)
91
+ }
92
+ promise.resolve(result)
93
+ } catch (e: Exception) {
94
+ // Return defaults if dev settings not available
95
+ val result = Arguments.createMap().apply {
96
+ putBoolean("isDebuggingRemotely", false)
97
+ putBoolean("isElementInspectorShown", false)
98
+ putBoolean("isHotLoadingEnabled", false)
99
+ putBoolean("isFastRefreshEnabled", false)
100
+ putBoolean("isPerfMonitorShown", false)
101
+ }
102
+ promise.resolve(result)
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Open native dev menu
108
+ */
109
+ @ReactMethod
110
+ fun openDevMenu() {
111
+ reactApplicationContext.runOnUiQueueThread {
112
+ try {
113
+ getDevSupportManager()?.showDevOptionsDialog()
114
+ } catch (e: Exception) {
115
+ // Ignore errors if dev support is not available
116
+ }
117
+ }
118
+ }
119
+
120
+ private fun getDevSupportManager() =
121
+ reactApplicationContext.currentActivity?.let { activity ->
122
+ (activity.application as? com.facebook.react.ReactApplication)
123
+ ?.reactNativeHost
124
+ ?.reactInstanceManager
125
+ ?.devSupportManager
126
+ }
127
+
128
+ private fun getDevSettings(): DevInternalSettings? =
129
+ getDevSupportManager()?.devSettings as? DevInternalSettings
130
+ }
@@ -0,0 +1,118 @@
1
+ package com.teardown.devclient
2
+
3
+ import android.hardware.Sensor
4
+ import android.hardware.SensorEvent
5
+ import android.hardware.SensorEventListener
6
+ import android.hardware.SensorManager
7
+ import android.content.Context
8
+ import com.facebook.react.bridge.*
9
+ import com.facebook.react.modules.core.DeviceEventManagerModule
10
+ import kotlin.math.sqrt
11
+
12
+ /**
13
+ * Native module for detecting shake gestures
14
+ */
15
+ class ShakeDetectorModule(private val reactContext: ReactApplicationContext) :
16
+ ReactContextBaseJavaModule(reactContext), SensorEventListener {
17
+
18
+ private var sensorManager: SensorManager? = null
19
+ private var accelerometer: Sensor? = null
20
+ private var isListening = false
21
+
22
+ // Shake detection parameters
23
+ private var lastShakeTime: Long = 0
24
+ private var lastX = 0f
25
+ private var lastY = 0f
26
+ private var lastZ = 0f
27
+ private var lastUpdate: Long = 0
28
+
29
+ companion object {
30
+ private const val SHAKE_THRESHOLD = 800
31
+ private const val SHAKE_SLOP_TIME_MS = 500
32
+ private const val SHAKE_COUNT_RESET_TIME_MS = 3000
33
+ }
34
+
35
+ override fun getName(): String = "TeardownShakeDetector"
36
+
37
+ override fun initialize() {
38
+ super.initialize()
39
+ sensorManager = reactContext.getSystemService(Context.SENSOR_SERVICE) as? SensorManager
40
+ accelerometer = sensorManager?.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
41
+ }
42
+
43
+ /**
44
+ * Start listening for shake gestures
45
+ */
46
+ @ReactMethod
47
+ fun startListening() {
48
+ if (isListening) return
49
+
50
+ accelerometer?.let { sensor ->
51
+ sensorManager?.registerListener(
52
+ this,
53
+ sensor,
54
+ SensorManager.SENSOR_DELAY_UI
55
+ )
56
+ isListening = true
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Stop listening for shake gestures
62
+ */
63
+ @ReactMethod
64
+ fun stopListening() {
65
+ if (!isListening) return
66
+
67
+ sensorManager?.unregisterListener(this)
68
+ isListening = false
69
+ }
70
+
71
+ override fun onSensorChanged(event: SensorEvent?) {
72
+ event ?: return
73
+
74
+ val currentTime = System.currentTimeMillis()
75
+
76
+ if ((currentTime - lastUpdate) > 100) {
77
+ val diffTime = currentTime - lastUpdate
78
+ lastUpdate = currentTime
79
+
80
+ val x = event.values[0]
81
+ val y = event.values[1]
82
+ val z = event.values[2]
83
+
84
+ val speed = sqrt(
85
+ ((x - lastX) * (x - lastX) +
86
+ (y - lastY) * (y - lastY) +
87
+ (z - lastZ) * (z - lastZ)).toDouble()
88
+ ) / diffTime * 10000
89
+
90
+ if (speed > SHAKE_THRESHOLD) {
91
+ // Debounce shake events
92
+ if (currentTime - lastShakeTime > SHAKE_SLOP_TIME_MS) {
93
+ lastShakeTime = currentTime
94
+ emitShakeEvent()
95
+ }
96
+ }
97
+
98
+ lastX = x
99
+ lastY = y
100
+ lastZ = z
101
+ }
102
+ }
103
+
104
+ override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
105
+ // Not needed
106
+ }
107
+
108
+ private fun emitShakeEvent() {
109
+ reactContext
110
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
111
+ .emit("TeardownShakeEvent", null)
112
+ }
113
+
114
+ override fun onCatalystInstanceDestroy() {
115
+ super.onCatalystInstanceDestroy()
116
+ stopListening()
117
+ }
118
+ }
@@ -0,0 +1,23 @@
1
+ package com.teardown.devclient
2
+
3
+ import com.facebook.react.ReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.uimanager.ViewManager
7
+
8
+ /**
9
+ * React Native package for Teardown Dev Client
10
+ */
11
+ class TeardownDevClientPackage : ReactPackage {
12
+
13
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
14
+ return listOf(
15
+ DevSettingsModule(reactContext),
16
+ ShakeDetectorModule(reactContext)
17
+ )
18
+ }
19
+
20
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
21
+ return emptyList()
22
+ }
23
+ }
@@ -0,0 +1,135 @@
1
+ //
2
+ // DevSettingsModule.swift
3
+ // TeardownDevClient
4
+ //
5
+ // Native module for controlling React Native dev settings
6
+ //
7
+
8
+ import Foundation
9
+ import React
10
+
11
+ @objc(TeardownDevSettings)
12
+ class DevSettingsModule: NSObject {
13
+
14
+ private var bridge: RCTBridge?
15
+
16
+ @objc
17
+ static func moduleName() -> String! {
18
+ return "TeardownDevSettings"
19
+ }
20
+
21
+ @objc
22
+ func setBridge(_ bridge: RCTBridge) {
23
+ self.bridge = bridge
24
+ }
25
+
26
+ /// Reload the JavaScript bundle
27
+ @objc
28
+ func reload() {
29
+ DispatchQueue.main.async {
30
+ RCTTriggerReloadCommandListeners("TeardownDevClient")
31
+ }
32
+ }
33
+
34
+ /// Open the debugger
35
+ @objc
36
+ func openDebugger() {
37
+ DispatchQueue.main.async {
38
+ #if DEBUG
39
+ // In debug mode, this would open the debugger
40
+ // The actual implementation depends on the debugger being used
41
+ NotificationCenter.default.post(
42
+ name: NSNotification.Name("RCTShowDevMenuNotification"),
43
+ object: nil
44
+ )
45
+ #endif
46
+ }
47
+ }
48
+
49
+ /// Toggle element inspector overlay
50
+ @objc
51
+ func toggleElementInspector() {
52
+ DispatchQueue.main.async {
53
+ #if DEBUG
54
+ if let devSettings = RCTDevSettings.sharedInstance() {
55
+ devSettings.toggleElementInspector()
56
+ }
57
+ #endif
58
+ }
59
+ }
60
+
61
+ /// Set hot loading enabled state
62
+ @objc(setHotLoadingEnabled:)
63
+ func setHotLoadingEnabled(_ enabled: Bool) {
64
+ DispatchQueue.main.async {
65
+ #if DEBUG
66
+ if let devSettings = RCTDevSettings.sharedInstance() {
67
+ devSettings.isHotLoadingEnabled = enabled
68
+ }
69
+ #endif
70
+ }
71
+ }
72
+
73
+ /// Set fast refresh enabled state
74
+ @objc(setFastRefreshEnabled:)
75
+ func setFastRefreshEnabled(_ enabled: Bool) {
76
+ // Fast refresh uses the same setting as hot loading in RN
77
+ setHotLoadingEnabled(enabled)
78
+ }
79
+
80
+ /// Get current dev settings
81
+ @objc(getDevSettings:rejecter:)
82
+ func getDevSettings(
83
+ _ resolve: @escaping RCTPromiseResolveBlock,
84
+ rejecter reject: @escaping RCTPromiseRejectBlock
85
+ ) {
86
+ DispatchQueue.main.async {
87
+ #if DEBUG
88
+ guard let devSettings = RCTDevSettings.sharedInstance() else {
89
+ let settings: [String: Any] = [
90
+ "isDebuggingRemotely": false,
91
+ "isElementInspectorShown": false,
92
+ "isHotLoadingEnabled": true,
93
+ "isFastRefreshEnabled": true,
94
+ "isPerfMonitorShown": false
95
+ ]
96
+ resolve(settings)
97
+ return
98
+ }
99
+
100
+ let settings: [String: Any] = [
101
+ "isDebuggingRemotely": devSettings.isDebuggingRemotely,
102
+ "isElementInspectorShown": devSettings.isElementInspectorShown,
103
+ "isHotLoadingEnabled": devSettings.isHotLoadingEnabled,
104
+ "isFastRefreshEnabled": devSettings.isHotLoadingEnabled,
105
+ "isPerfMonitorShown": devSettings.isPerfMonitorShown
106
+ ]
107
+
108
+ resolve(settings)
109
+ #else
110
+ // In release mode, return defaults
111
+ let settings: [String: Any] = [
112
+ "isDebuggingRemotely": false,
113
+ "isElementInspectorShown": false,
114
+ "isHotLoadingEnabled": false,
115
+ "isFastRefreshEnabled": false,
116
+ "isPerfMonitorShown": false
117
+ ]
118
+ resolve(settings)
119
+ #endif
120
+ }
121
+ }
122
+
123
+ /// Open native dev menu
124
+ @objc
125
+ func openDevMenu() {
126
+ DispatchQueue.main.async {
127
+ #if DEBUG
128
+ NotificationCenter.default.post(
129
+ name: NSNotification.Name("RCTShowDevMenuNotification"),
130
+ object: nil
131
+ )
132
+ #endif
133
+ }
134
+ }
135
+ }
@@ -0,0 +1,102 @@
1
+ //
2
+ // ShakeDetector.swift
3
+ // TeardownDevClient
4
+ //
5
+ // Native module for detecting shake gestures
6
+ //
7
+
8
+ import Foundation
9
+ import UIKit
10
+ import React
11
+
12
+ @objc(TeardownShakeDetector)
13
+ class ShakeDetector: RCTEventEmitter {
14
+
15
+ private var isListening = false
16
+ private var motionManager: CMMotionManager?
17
+
18
+ override init() {
19
+ super.init()
20
+ setupShakeNotification()
21
+ }
22
+
23
+ @objc
24
+ override static func moduleName() -> String! {
25
+ return "TeardownShakeDetector"
26
+ }
27
+
28
+ @objc
29
+ override static func requiresMainQueueSetup() -> Bool {
30
+ return true
31
+ }
32
+
33
+ @objc
34
+ override func supportedEvents() -> [String]! {
35
+ return ["TeardownShakeEvent"]
36
+ }
37
+
38
+ private func setupShakeNotification() {
39
+ // Listen for shake motion events from the app delegate
40
+ NotificationCenter.default.addObserver(
41
+ self,
42
+ selector: #selector(handleShakeMotion),
43
+ name: NSNotification.Name("TeardownShakeMotion"),
44
+ object: nil
45
+ )
46
+ }
47
+
48
+ @objc
49
+ private func handleShakeMotion() {
50
+ guard isListening else { return }
51
+
52
+ DispatchQueue.main.async {
53
+ self.sendEvent(withName: "TeardownShakeEvent", body: nil)
54
+ }
55
+ }
56
+
57
+ /// Start listening for shake gestures
58
+ @objc
59
+ func startListening() {
60
+ isListening = true
61
+ }
62
+
63
+ /// Stop listening for shake gestures
64
+ @objc
65
+ func stopListening() {
66
+ isListening = false
67
+ }
68
+
69
+ deinit {
70
+ NotificationCenter.default.removeObserver(self)
71
+ }
72
+ }
73
+
74
+ // MARK: - UIWindow Extension for Shake Detection
75
+
76
+ // This extension should be added to the app's AppDelegate to enable shake detection
77
+ // Example usage in AppDelegate:
78
+ //
79
+ // override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
80
+ // if motion == .motionShake {
81
+ // NotificationCenter.default.post(name: NSNotification.Name("TeardownShakeMotion"), object: nil)
82
+ // }
83
+ // }
84
+
85
+ import CoreMotion
86
+
87
+ private var associatedMotionManagerKey: UInt8 = 0
88
+
89
+ extension UIWindow {
90
+
91
+ /// Override to detect shake motion
92
+ open override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
93
+ super.motionEnded(motion, with: event)
94
+
95
+ if motion == .motionShake {
96
+ NotificationCenter.default.post(
97
+ name: NSNotification.Name("TeardownShakeMotion"),
98
+ object: nil
99
+ )
100
+ }
101
+ }
102
+ }
@@ -0,0 +1,14 @@
1
+ //
2
+ // TeardownDevClient.h
3
+ // TeardownDevClient
4
+ //
5
+ // Umbrella header for TeardownDevClient native module
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+
10
+ //! Project version number for TeardownDevClient.
11
+ FOUNDATION_EXPORT double TeardownDevClientVersionNumber;
12
+
13
+ //! Project version string for TeardownDevClient.
14
+ FOUNDATION_EXPORT const unsigned char TeardownDevClientVersionString[];
@@ -0,0 +1,42 @@
1
+ //
2
+ // TeardownDevClient.mm
3
+ // TeardownDevClient
4
+ //
5
+ // Bridge file for React Native integration
6
+ //
7
+
8
+ #import <React/RCTBridgeModule.h>
9
+ #import <React/RCTEventEmitter.h>
10
+
11
+ // TeardownDevSettings module
12
+ @interface RCT_EXTERN_MODULE(TeardownDevSettings, NSObject)
13
+
14
+ RCT_EXTERN_METHOD(reload)
15
+ RCT_EXTERN_METHOD(openDebugger)
16
+ RCT_EXTERN_METHOD(toggleElementInspector)
17
+ RCT_EXTERN_METHOD(setHotLoadingEnabled:(BOOL)enabled)
18
+ RCT_EXTERN_METHOD(setFastRefreshEnabled:(BOOL)enabled)
19
+ RCT_EXTERN_METHOD(getDevSettings:(RCTPromiseResolveBlock)resolve
20
+ rejecter:(RCTPromiseRejectBlock)reject)
21
+ RCT_EXTERN_METHOD(openDevMenu)
22
+
23
+ + (BOOL)requiresMainQueueSetup
24
+ {
25
+ return YES;
26
+ }
27
+
28
+ @end
29
+
30
+ // TeardownShakeDetector module
31
+ @interface RCT_EXTERN_MODULE(TeardownShakeDetector, RCTEventEmitter)
32
+
33
+ RCT_EXTERN_METHOD(startListening)
34
+ RCT_EXTERN_METHOD(stopListening)
35
+ RCT_EXTERN_METHOD(supportedEvents)
36
+
37
+ + (BOOL)requiresMainQueueSetup
38
+ {
39
+ return YES;
40
+ }
41
+
42
+ @end
@@ -0,0 +1,23 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "TeardownDevClient"
7
+ s.version = package['version']
8
+ s.summary = "Development client for Teardown React Native apps"
9
+ s.description = <<-DESC
10
+ Provides development client functionality including dev menu,
11
+ splash screen control, and shake detection for Teardown apps.
12
+ DESC
13
+ s.homepage = "https://github.com/teardown-dev/teardown"
14
+ s.license = package['license']
15
+ s.authors = { "Teardown" => "dev@teardown.dev" }
16
+ s.platforms = { :ios => "13.4" }
17
+ s.source = { :git => "https://github.com/teardown-dev/teardown.git", :tag => "v#{s.version}" }
18
+
19
+ s.source_files = "TeardownDevClient/**/*.{h,m,mm,swift}"
20
+ s.swift_version = "5.0"
21
+
22
+ s.dependency "React-Core"
23
+ end
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@teardown/dev-client",
3
+ "version": "2.0.44",
4
+ "private": false,
5
+ "type": "module",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "files": [
10
+ "src/**/*",
11
+ "ios/**/*",
12
+ "android/**/*"
13
+ ],
14
+ "main": "./src/index.ts",
15
+ "module": "./src/index.ts",
16
+ "types": "./src/index.ts",
17
+ "exports": {
18
+ "./package.json": "./package.json",
19
+ ".": {
20
+ "types": "./src/index.ts",
21
+ "import": "./src/index.ts",
22
+ "default": "./src/index.ts"
23
+ }
24
+ },
25
+ "scripts": {
26
+ "typecheck": "tsc --noEmit --project ./tsconfig.json",
27
+ "lint": "bun x biome lint --write ./src",
28
+ "fmt": "bun x biome format --write ./src",
29
+ "check": "bun x biome check ./src",
30
+ "test": "bun test"
31
+ },
32
+ "dependencies": {
33
+ "eventemitter3": "^5.0.1"
34
+ },
35
+ "devDependencies": {
36
+ "@biomejs/biome": "2.3.11",
37
+ "@teardown/tsconfig": "2.0.44",
38
+ "@types/bun": "1.3.5",
39
+ "@types/react": "~19.1.0",
40
+ "react": "19.1.0",
41
+ "react-native": "0.81.5",
42
+ "typescript": "5.9.3"
43
+ },
44
+ "peerDependencies": {
45
+ "react": ">=18",
46
+ "react-native": ">=0.73"
47
+ },
48
+ "peerDependenciesMeta": {
49
+ "react": {
50
+ "optional": false
51
+ },
52
+ "react-native": {
53
+ "optional": false
54
+ }
55
+ }
56
+ }