@mentra/crust 0.1.0-dev.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.
Files changed (66) hide show
  1. package/README.md +35 -0
  2. package/android/build.gradle +146 -0
  3. package/android/src/internal/AndroidManifest.xml +9 -0
  4. package/android/src/internal/java/com/mentra/crust/receivers/CaptionsTesterIncidentReceiver.kt +46 -0
  5. package/android/src/main/AndroidManifest.xml +19 -0
  6. package/android/src/main/java/com/mentra/crust/CrustModule.kt +882 -0
  7. package/android/src/main/java/com/mentra/crust/CrustView.kt +30 -0
  8. package/android/src/main/java/com/mentra/crust/heading/HeadingManager.kt +150 -0
  9. package/android/src/main/java/com/mentra/crust/jsc/JSCDispatcher.kt +189 -0
  10. package/android/src/main/java/com/mentra/crust/jsc/JSCPolyfillBridge.kt +246 -0
  11. package/android/src/main/java/com/mentra/crust/jsc/JSCRuntime.kt +593 -0
  12. package/android/src/main/java/com/mentra/crust/navigation/NavigationManager.kt +1445 -0
  13. package/android/src/main/java/com/mentra/crust/services/NotificationListener.kt +319 -0
  14. package/android/src/main/java/com/mentra/crust/utils/ImageProcessor.java +452 -0
  15. package/android/src/main/java/com/mentra/crust/utils/VideoStabilizer.kt +556 -0
  16. package/android/src/main/res/values/strings.xml +3 -0
  17. package/app.plugin.js +3 -0
  18. package/build/Crust.types.d.ts +148 -0
  19. package/build/Crust.types.d.ts.map +1 -0
  20. package/build/Crust.types.js +2 -0
  21. package/build/Crust.types.js.map +1 -0
  22. package/build/CrustModule.d.ts +175 -0
  23. package/build/CrustModule.d.ts.map +1 -0
  24. package/build/CrustModule.js +4 -0
  25. package/build/CrustModule.js.map +1 -0
  26. package/build/CrustModule.web.d.ts +26 -0
  27. package/build/CrustModule.web.d.ts.map +1 -0
  28. package/build/CrustModule.web.js +54 -0
  29. package/build/CrustModule.web.js.map +1 -0
  30. package/build/CrustView.d.ts +4 -0
  31. package/build/CrustView.d.ts.map +1 -0
  32. package/build/CrustView.js +7 -0
  33. package/build/CrustView.js.map +1 -0
  34. package/build/CrustView.web.d.ts +4 -0
  35. package/build/CrustView.web.d.ts.map +1 -0
  36. package/build/CrustView.web.js +7 -0
  37. package/build/CrustView.web.js.map +1 -0
  38. package/build/index.d.ts +4 -0
  39. package/build/index.d.ts.map +1 -0
  40. package/build/index.js +6 -0
  41. package/build/index.js.map +1 -0
  42. package/expo-module.config.json +9 -0
  43. package/ios/Crust.podspec +65 -0
  44. package/ios/CrustModule.swift +544 -0
  45. package/ios/CrustView.swift +38 -0
  46. package/ios/Resources/startup.js +814 -0
  47. package/ios/Source/JSCDispatcher.swift +226 -0
  48. package/ios/Source/JSCPolyfillBridge.swift +378 -0
  49. package/ios/Source/JSCRuntime.swift +673 -0
  50. package/ios/Source/utils/ImageProcessor.swift +392 -0
  51. package/ios/Source/utils/SystemGestures.swift +53 -0
  52. package/ios/Source/utils/VideoStabilizer.swift +374 -0
  53. package/ios/heading/HeadingManager.swift +74 -0
  54. package/ios/navigation/NavPayloads.swift +62 -0
  55. package/ios/navigation/NavigationManager.swift +720 -0
  56. package/package.json +69 -0
  57. package/plugin/build/index.d.ts +19 -0
  58. package/plugin/build/index.js +23 -0
  59. package/plugin/build/withAndroid.d.ts +2 -0
  60. package/plugin/build/withAndroid.js +78 -0
  61. package/src/Crust.types.ts +157 -0
  62. package/src/CrustModule.ts +186 -0
  63. package/src/CrustModule.web.ts +57 -0
  64. package/src/CrustView.tsx +10 -0
  65. package/src/CrustView.web.tsx +11 -0
  66. package/src/index.ts +5 -0
package/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # crust
2
+
3
+ Mentra Native Module
4
+
5
+ # API documentation
6
+
7
+ - [Documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/crust/)
8
+ - [Documentation for the main branch](https://docs.expo.dev/versions/unversioned/sdk/crust/)
9
+
10
+ # Installation in managed Expo projects
11
+
12
+ For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](#api-documentation). If you follow the link and there is no documentation available then this library is not yet usable within managed projects — it is likely to be included in an upcoming Expo SDK release.
13
+
14
+ # Installation in bare React Native projects
15
+
16
+ For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
17
+
18
+ ### Add the package to your npm dependencies
19
+
20
+ ```
21
+ npm install crust
22
+ ```
23
+
24
+ ### Configure for Android
25
+
26
+
27
+
28
+
29
+ ### Configure for iOS
30
+
31
+ Run `npx pod-install` after installing the npm package.
32
+
33
+ # Contributing
34
+
35
+ Contributions are very welcome! Please refer to guidelines described in the [contributing guide]( https://github.com/expo/expo#contributing).
@@ -0,0 +1,146 @@
1
+ apply plugin: 'com.android.library'
2
+
3
+ group = 'com.mentra.crust'
4
+ version = '0.1.0'
5
+
6
+ def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
7
+ apply from: expoModulesCorePlugin
8
+ applyKotlinExpoModulesCorePlugin()
9
+ useCoreDependencies()
10
+ useExpoPublishing()
11
+
12
+ // MentraJS Android runtime: QuickJS via dokar3/quickjs-kt.
13
+ //
14
+ // Zipline's `bind(name, service)` registers services in an internal Kotlin
15
+ // map keyed by name for the Kotlin/JS-compiled `Zipline.take()` API; it does
16
+ // not install JS globals on globalThis. Our polyfill is hand-written JS that
17
+ // reads `globalThis.__mentraNativeBridge`, so the Zipline path silently
18
+ // dropped every JS→host dispatch on Android.
19
+ //
20
+ // dokar3/quickjs-kt exposes `QuickJs.function(name) { args -> ... }` which
21
+ // installs the lambda directly as a property of globalThis via QuickJS's
22
+ // `JS_SetPropertyStr(JS_NewCFunction(...))`. This matches iOS Apple JSC's
23
+ // `ctx.setObject(closure, forKeyedSubscript: ...)` pattern point-for-point.
24
+
25
+ // If you want to use the managed Android SDK versions from expo-modules-core, set this to true.
26
+ // The Android SDK versions will be bumped from time to time in SDK releases and may introduce breaking changes in your module code.
27
+ // Most of the time, you may like to manage the Android SDK versions yourself.
28
+ def useManagedAndroidSdkVersions = false
29
+ if (useManagedAndroidSdkVersions) {
30
+ useDefaultAndroidSdkVersions()
31
+ } else {
32
+ buildscript {
33
+ // Simple helper that allows the root project to override versions declared by this library.
34
+ ext.safeExtGet = { prop, fallback ->
35
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
36
+ }
37
+ }
38
+ project.android {
39
+ compileSdkVersion safeExtGet("compileSdkVersion", 36)
40
+ defaultConfig {
41
+ minSdkVersion safeExtGet("minSdkVersion", 24)
42
+ targetSdkVersion safeExtGet("targetSdkVersion", 36)
43
+ }
44
+ }
45
+ }
46
+
47
+ android {
48
+ namespace "com.mentra.crust"
49
+ defaultConfig {
50
+ versionCode 1
51
+ versionName "0.1.0"
52
+ multiDexEnabled true
53
+ }
54
+ // Pull the MentraJS polyfill bundle from the sibling @mentra/jspolyfill
55
+ // module's `assets/` directory — single committed source of truth. The
56
+ // file is read at runtime via `appContext.assets.open("startup.js")`.
57
+ // Cross-module sourceSet entry beats checking the same artifact into git
58
+ // multiple times.
59
+ sourceSets {
60
+ main {
61
+ assets.srcDirs += '../../jspolyfill/assets'
62
+ }
63
+ }
64
+ compileOptions {
65
+ coreLibraryDesugaringEnabled true
66
+ }
67
+ buildTypes {
68
+ internal {
69
+ initWith release
70
+ matchingFallbacks = ['release']
71
+ }
72
+ }
73
+ buildTypes {
74
+ internal {
75
+ initWith release
76
+ matchingFallbacks = ['release']
77
+ }
78
+ }
79
+ lintOptions {
80
+ abortOnError false
81
+ }
82
+ }
83
+
84
+ dependencies {
85
+ // Mapbox Navigation SDK v3 (replaces Google Navigation SDK).
86
+ // Drives headless turn-by-turn nav in NavigationManager.kt: route
87
+ // progress, off-route + automatic rerouting, enhanced (map-matched)
88
+ // location, and the MapboxReplayer simulation harness for dev trips.
89
+ // Resolved from the authenticated Mapbox Downloads Maven repo, which is
90
+ // injected into the root project's allprojects.repositories at prebuild by
91
+ // mobile/plugins/android.ts (withProjectBuildGradleModifications), using the
92
+ // MAPBOX_DOWNLOADS_TOKEN (Downloads:Read sk.… token) from the env/gradle.properties.
93
+ //
94
+ // We depend on the headless modules directly, NOT the umbrella
95
+ // `navigationcore:android` artifact — that one also drags in `ui-maps`,
96
+ // `voice`, and `copilot`, which a custom glasses HUD doesn't use (dead
97
+ // APK weight). `:navigation` is the core engine; `:tripdata` carries the
98
+ // banner/maneuver formatting used to label turns.
99
+ // Version pinned to 3.25.0 — re-check https://docs.mapbox.com/android/navigation/releases/
100
+ def isChinaBuild = System.getenv("EXPO_PUBLIC_DEPLOYMENT_REGION") == "china"
101
+ if (isChinaBuild) {
102
+ compileOnly 'com.mapbox.navigationcore:navigation:3.25.0'
103
+ compileOnly 'com.mapbox.navigationcore:tripdata:3.25.0'
104
+ } else {
105
+ implementation 'com.mapbox.navigationcore:navigation:3.25.0'
106
+ implementation 'com.mapbox.navigationcore:tripdata:3.25.0'
107
+ }
108
+
109
+ // Required for Java 8+ APIs on minSdk < 26 (was needed by Google Nav SDK;
110
+ // Mapbox Nav SDK likewise targets desugared core libs).
111
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.4'
112
+ }
113
+
114
+ dependencies {
115
+ implementation 'com.google.android.gms:play-services-location:21.0.1'
116
+ implementation 'com.google.android.gms:play-services-base:18.2.0'
117
+ }
118
+
119
+ dependencies {
120
+ // MentraJS — QuickJS for per-miniapp JS contexts. dokar3/quickjs-kt is a
121
+ // KMP wrapper around Bellard QuickJS that exposes `function(name) { ... }`
122
+ // for installing Kotlin lambdas as JS globals via `JS_SetPropertyStr`.
123
+ // Mirrors iOS Apple JSC's `setObject(_, forKeyedSubscript:)` pattern.
124
+ //
125
+ // Version pin: this Expo SDK 55 build uses Kotlin 2.1.20, which can read
126
+ // metadata up to 2.2.0. dokar3 1.0.1+ ships classes with metadata 2.3.0
127
+ // (compiled with Kotlin 2.3.x) and is unreadable here. 1.0.0-alpha13 is
128
+ // the last release compiled with Kotlin 2.0 (metadata 2.0.0) — its API
129
+ // (`QuickJs.create`, `evaluate`, `function` extension) matches 1.0.5 1:1.
130
+ // Bump only when the host Kotlin compiler clears 2.3.0 metadata.
131
+ implementation 'io.github.dokar3:quickjs-kt-android:1.0.0-alpha13'
132
+
133
+ // OkHttp for fetch / WebSocket — already used elsewhere in MentraOS;
134
+ // pinned here so the gradle plugin doesn't downgrade us.
135
+ implementation 'com.squareup.okhttp3:okhttp:4.12.0'
136
+
137
+ // Tink for X25519 (Android stdlib X25519 is API 33+ only; minSdk is 24).
138
+ // ~1.2 MB AAR. Crypto.subtle's SHA / AES-GCM / HMAC stay on javax.crypto
139
+ // which ships on the platform.
140
+ implementation 'com.google.crypto.tink:tink-android:1.14.1'
141
+
142
+ // Kotlin coroutines: dokar3's `evaluate()` is suspend; we bridge it via
143
+ // `runBlocking(dispatcher)` from the per-miniapp single-thread executor.
144
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1'
145
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1'
146
+ }
@@ -0,0 +1,9 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <application>
3
+ <receiver android:name="com.mentra.crust.receivers.CaptionsTesterIncidentReceiver" android:exported="true">
4
+ <intent-filter>
5
+ <action android:name="com.mentra.CAPTIONS_TESTER_INCIDENT"/>
6
+ </intent-filter>
7
+ </receiver>
8
+ </application>
9
+ </manifest>
@@ -0,0 +1,46 @@
1
+ package com.mentra.crust.receivers
2
+
3
+ import android.content.BroadcastReceiver
4
+ import android.content.Context
5
+ import android.content.Intent
6
+ import android.util.Log
7
+ import com.mentra.crust.CrustModule
8
+
9
+ /**
10
+ * Receives broadcasts from the external captions tester and forwards them into React Native so
11
+ * the app can file a normal incident through the existing mobile incident pipeline.
12
+ */
13
+ class CaptionsTesterIncidentReceiver : BroadcastReceiver() {
14
+ @Suppress("DEPRECATION")
15
+ override fun onReceive(context: Context?, intent: Intent?) {
16
+ if (intent == null) {
17
+ Log.w("CaptionsTesterIncident", "Received null intent")
18
+ return
19
+ }
20
+
21
+ val body =
22
+ hashMapOf<String, Any>(
23
+ "action" to (intent.action ?: "unknown"),
24
+ "timestamp" to System.currentTimeMillis(),
25
+ )
26
+
27
+ intent.getStringExtra("failure_code")?.let { body["failure_code"] = it }
28
+ intent.getStringExtra("failure_message")?.let { body["failure_message"] = it }
29
+ intent.getStringExtra("test_run_id")?.let { body["test_run_id"] = it }
30
+ intent.getStringExtra("scenario_name")?.let { body["scenario_name"] = it }
31
+ intent.getStringExtra("source")?.let { body["source"] = it }
32
+
33
+ intent.extras?.keySet()?.forEach { key ->
34
+ if (body.containsKey(key)) {
35
+ return@forEach
36
+ }
37
+ val value = intent.extras?.get(key) ?: return@forEach
38
+ when (value) {
39
+ is String, is Int, is Long, is Boolean, is Double, is Float -> body[key] = value
40
+ else -> body[key] = value.toString()
41
+ }
42
+ }
43
+
44
+ CrustModule.emitCaptionsTesterIncident(body)
45
+ }
46
+ }
@@ -0,0 +1,19 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <application>
3
+ <service
4
+ android:name="com.mentra.crust.services.NotificationListenerServiceImpl"
5
+ android:label="@string/mentra_crust_notification_listener_label"
6
+ android:exported="false"
7
+ android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
8
+ <intent-filter>
9
+ <action android:name="android.service.notification.NotificationListenerService" />
10
+ </intent-filter>
11
+ <meta-data android:name="android.service.notification.default_filter_types" android:value="conversations|alerting" />
12
+ <meta-data android:name="android.service.notification.disabled_filter_types" android:value="ongoing|silent" />
13
+ </service>
14
+
15
+ <!-- The Mapbox Navigation SDK delivers turn-by-turn steps inline via
16
+ RouteProgress (no Messenger-IPC service), so the Google-era
17
+ NavInfoReceiverService is gone. Nothing to register here for nav. -->
18
+ </application>
19
+ </manifest>