@mentra/crust 3.2.1-dev.314 → 3.3.0-beta.942
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 +27 -0
- package/android/build.gradle +18 -9
- package/android/src/main/AndroidManifest.xml +7 -0
- package/android/src/main/java/com/mentra/crust/CrustModule.kt +76 -22
- package/android/src/main/java/com/mentra/crust/http/NativeHttpFailure.kt +31 -0
- package/android/src/main/java/com/mentra/crust/http/NativeHttpRequests.kt +86 -0
- package/android/src/main/java/com/mentra/crust/jsc/JSCPolyfillBridge.kt +6 -35
- package/android/src/main/java/com/mentra/crust/jsc/JSCRuntime.kt +65 -8
- package/android/src/main/java/com/mentra/crust/jsc/JSDeliveryDiagnostics.kt +44 -0
- package/android/src/main/java/com/mentra/crust/navigation/NavigationManager.kt +74 -10
- package/android/src/main/java/com/mentra/crust/navigation/NavigationSessionGuard.kt +74 -0
- package/android/src/main/java/com/mentra/crust/preview/PixelCopyPreview.kt +76 -0
- package/android/src/main/java/com/mentra/crust/services/RuntimeRecoveryService.kt +12 -0
- package/android/src/test/java/com/mentra/crust/http/NativeHttpFailureTest.kt +44 -0
- package/android/src/test/java/com/mentra/crust/http/NativeHttpRequestsTest.kt +133 -0
- package/android/src/test/java/com/mentra/crust/jsc/HttpRequestTest.kt +32 -0
- package/android/src/test/java/com/mentra/crust/jsc/JSDeliveryDiagnosticsTest.kt +54 -0
- package/android/src/test/java/com/mentra/crust/jsc/QuickJsLifecycleTest.kt +87 -0
- package/android/src/test/java/com/mentra/crust/navigation/NavigationSessionGuardTest.kt +68 -0
- package/build/Crust.types.d.ts +25 -11
- package/build/Crust.types.d.ts.map +1 -1
- package/build/Crust.types.js.map +1 -1
- package/build/CrustModule.d.ts +11 -2
- package/build/CrustModule.d.ts.map +1 -1
- package/build/CrustModule.js.map +1 -1
- package/build/CrustModule.web.d.ts +3 -1
- package/build/CrustModule.web.d.ts.map +1 -1
- package/build/CrustModule.web.js +20 -8
- package/build/CrustModule.web.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/nativeHttpRequest.d.ts +13 -0
- package/build/nativeHttpRequest.d.ts.map +1 -0
- package/build/nativeHttpRequest.js +51 -0
- package/build/nativeHttpRequest.js.map +1 -0
- package/build/nativeHttpRequest.test.d.ts +2 -0
- package/build/nativeHttpRequest.test.d.ts.map +1 -0
- package/build/nativeHttpRequest.test.js +88 -0
- package/build/nativeHttpRequest.test.js.map +1 -0
- package/ios/Crust.podspec +1 -1
- package/ios/CrustModule.swift +22 -7
- package/ios/PermissionStatusReceipt.swift +105 -0
- package/package.json +2 -2
- package/plugin/build/index.d.ts +2 -0
- package/plugin/build/index.js +2 -0
- package/plugin/build/withAndroid.js +39 -0
- package/src/Crust.types.ts +26 -12
- package/src/CrustModule.ts +11 -1
- package/src/CrustModule.web.ts +18 -7
- package/src/index.ts +1 -0
- package/src/nativeHttpRequest.test.ts +94 -0
- package/src/nativeHttpRequest.ts +74 -0
- package/android/src/internal/AndroidManifest.xml +0 -9
- package/android/src/internal/java/com/mentra/crust/receivers/CaptionsTesterIncidentReceiver.kt +0 -46
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export interface NativeHttpResult {
|
|
2
|
+
status: number
|
|
3
|
+
statusText: string
|
|
4
|
+
headers: Record<string, string>
|
|
5
|
+
body: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface NativeHttpTransport {
|
|
9
|
+
nativeHttpRequest(
|
|
10
|
+
requestId: string,
|
|
11
|
+
method: string,
|
|
12
|
+
url: string,
|
|
13
|
+
headers: Record<string, string>,
|
|
14
|
+
body: string | null,
|
|
15
|
+
): Promise<NativeHttpResult>
|
|
16
|
+
cancelNativeHttpRequest(requestId: string): Promise<void>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let requestSequence = 0
|
|
20
|
+
|
|
21
|
+
function abortReason(signal: AbortSignal): unknown {
|
|
22
|
+
if (signal.reason !== undefined) return signal.reason
|
|
23
|
+
const error = new Error("Native HTTP request aborted")
|
|
24
|
+
error.name = "AbortError"
|
|
25
|
+
return error
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Keep Android's background-safe HTTP path while cancelling its actual native request. */
|
|
29
|
+
export function nativeHttpRequest(
|
|
30
|
+
native: NativeHttpTransport,
|
|
31
|
+
method: string,
|
|
32
|
+
url: string,
|
|
33
|
+
headers: Record<string, string>,
|
|
34
|
+
body: string | null,
|
|
35
|
+
signal?: AbortSignal,
|
|
36
|
+
): Promise<NativeHttpResult> {
|
|
37
|
+
if (signal?.aborted) return Promise.reject(abortReason(signal))
|
|
38
|
+
const requestId = `http-${Date.now().toString(36)}-${++requestSequence}`
|
|
39
|
+
// Start first, then subscribe: Expo delivers start and cancel on the same serial queue.
|
|
40
|
+
const request = native.nativeHttpRequest(requestId, method, url, headers, body)
|
|
41
|
+
if (!signal) return request
|
|
42
|
+
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
let settled = false
|
|
45
|
+
let cancelling = false
|
|
46
|
+
const finish = (action: () => void) => {
|
|
47
|
+
if (settled) return
|
|
48
|
+
settled = true
|
|
49
|
+
signal.removeEventListener("abort", onAbort)
|
|
50
|
+
action()
|
|
51
|
+
}
|
|
52
|
+
const onAbort = () => {
|
|
53
|
+
if (settled || cancelling) return
|
|
54
|
+
cancelling = true
|
|
55
|
+
void native.cancelNativeHttpRequest(requestId).then(
|
|
56
|
+
() => finish(() => reject(abortReason(signal))),
|
|
57
|
+
(error: unknown) => finish(() => reject(error)),
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
request.then(
|
|
61
|
+
(result) => {
|
|
62
|
+
if (signal.aborted) onAbort()
|
|
63
|
+
else finish(() => resolve(result))
|
|
64
|
+
},
|
|
65
|
+
(error: unknown) => {
|
|
66
|
+
if (signal.aborted) onAbort()
|
|
67
|
+
else finish(() => reject(error))
|
|
68
|
+
},
|
|
69
|
+
)
|
|
70
|
+
signal.addEventListener("abort", onAbort, {once: true})
|
|
71
|
+
// Handles an abort fired synchronously during native registration.
|
|
72
|
+
if (signal.aborted) onAbort()
|
|
73
|
+
})
|
|
74
|
+
}
|
|
@@ -1,9 +0,0 @@
|
|
|
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>
|
package/android/src/internal/java/com/mentra/crust/receivers/CaptionsTesterIncidentReceiver.kt
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
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
|
-
}
|