@glassly/crust 0.3.5 → 0.3.6-dev.846
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/android/build.gradle +12 -12
- package/android/src/main/java/com/glassly/crust/CrustModule.kt +2 -0
- package/android/src/main/java/com/glassly/crust/jsc/JSCPolyfillBridge.kt +17 -4
- package/build/Crust.types.d.ts +6 -0
- package/build/Crust.types.d.ts.map +1 -1
- package/build/Crust.types.js.map +1 -1
- package/build/CrustModule.d.ts +7 -1
- package/build/CrustModule.d.ts.map +1 -1
- package/build/CrustModule.js.map +1 -1
- package/build/CrustModule.web.d.ts +2 -1
- package/build/CrustModule.web.d.ts.map +1 -1
- package/build/CrustModule.web.js +3 -0
- package/build/CrustModule.web.js.map +1 -1
- package/ios/CrustModule.swift +18 -0
- package/ios/Resources/startup.js +34 -21
- package/ios/Source/JSCPolyfillBridge.swift +14 -3
- package/package.json +2 -2
- package/src/Crust.types.ts +7 -0
- package/src/CrustModule.ts +7 -1
- package/src/CrustModule.web.ts +3 -0
package/android/build.gradle
CHANGED
|
@@ -95,15 +95,17 @@ dependencies {
|
|
|
95
95
|
// `navigationcore:android` artifact — that one also drags in `ui-maps`,
|
|
96
96
|
// `voice`, and `copilot`, which a custom glasses HUD doesn't use (dead
|
|
97
97
|
// APK weight). `:navigation` is the core engine; `:tripdata` carries the
|
|
98
|
-
// banner/maneuver formatting used to label turns.
|
|
98
|
+
// banner/maneuver formatting used to label turns. The -ndk27 variants are
|
|
99
|
+
// the 16 KB page size builds Google Play requires; the plain artifacts are
|
|
100
|
+
// 4 KB aligned.
|
|
99
101
|
// Version pinned to 3.25.0 — re-check https://docs.mapbox.com/android/navigation/releases/
|
|
100
102
|
def isChinaBuild = System.getenv("EXPO_PUBLIC_DEPLOYMENT_REGION") == "china"
|
|
101
103
|
if (isChinaBuild) {
|
|
102
|
-
compileOnly 'com.mapbox.navigationcore:navigation:3.25.0'
|
|
103
|
-
compileOnly 'com.mapbox.navigationcore:tripdata:3.25.0'
|
|
104
|
+
compileOnly 'com.mapbox.navigationcore:navigation-ndk27:3.25.0'
|
|
105
|
+
compileOnly 'com.mapbox.navigationcore:tripdata-ndk27:3.25.0'
|
|
104
106
|
} else {
|
|
105
|
-
implementation 'com.mapbox.navigationcore:navigation:3.25.0'
|
|
106
|
-
implementation 'com.mapbox.navigationcore:tripdata:3.25.0'
|
|
107
|
+
implementation 'com.mapbox.navigationcore:navigation-ndk27:3.25.0'
|
|
108
|
+
implementation 'com.mapbox.navigationcore:tripdata-ndk27:3.25.0'
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
// Required for Java 8+ APIs on minSdk < 26 (was needed by Google Nav SDK;
|
|
@@ -122,13 +124,11 @@ dependencies {
|
|
|
122
124
|
// for installing Kotlin lambdas as JS globals via `JS_SetPropertyStr`.
|
|
123
125
|
// Mirrors iOS Apple JSC's `setObject(_, forKeyedSubscript:)` pattern.
|
|
124
126
|
//
|
|
125
|
-
// Version pin:
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
|
|
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'
|
|
127
|
+
// Version pin: 1.0.1+ ships Kotlin 2.3 metadata, which the host Kotlin 2.2
|
|
128
|
+
// compiler can read. 1.0.0-alpha13 and older ship 4 KB-aligned
|
|
129
|
+
// libquickjs.so, which Google Play rejects (16 KB page size requirement).
|
|
130
|
+
// 1.0.8+ needs Kotlin 2.4 metadata.
|
|
131
|
+
implementation 'io.github.dokar3:quickjs-kt-android:1.0.5'
|
|
132
132
|
|
|
133
133
|
// OkHttp for fetch / WebSocket — already used elsewhere in Glassly;
|
|
134
134
|
// pinned here so the gradle plugin doesn't downgrade us.
|
|
@@ -219,6 +219,13 @@ object JSCPolyfillBridge {
|
|
|
219
219
|
ks to vs
|
|
220
220
|
}?.toMap() ?: emptyMap()
|
|
221
221
|
val bodyString = req["body"] as? String
|
|
222
|
+
val bodyBytes = (req["bodyBase64"] as? String)?.let { encoded ->
|
|
223
|
+
try {
|
|
224
|
+
Base64.decode(encoded, Base64.DEFAULT)
|
|
225
|
+
} catch (e: IllegalArgumentException) {
|
|
226
|
+
return@register JSCDispatchOutcome.Error("INVALID_ARGS", "fetch.request: bodyBase64 is not base64")
|
|
227
|
+
}
|
|
228
|
+
}
|
|
222
229
|
|
|
223
230
|
val builder = Request.Builder().url(url)
|
|
224
231
|
for ((k, v) in headers) builder.header(k, v)
|
|
@@ -228,10 +235,16 @@ object JSCPolyfillBridge {
|
|
|
228
235
|
val contentType = headers.entries
|
|
229
236
|
.firstOrNull { (name, _) -> name.equals("content-type", ignoreCase = true) }
|
|
230
237
|
?.value
|
|
231
|
-
val
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
238
|
+
val mediaType = (contentType ?: "application/octet-stream").toMediaTypeOrNull()
|
|
239
|
+
val upperMethod = method.uppercase()
|
|
240
|
+
val body = when {
|
|
241
|
+
upperMethod == "GET" || upperMethod == "HEAD" -> null
|
|
242
|
+
bodyBytes != null -> bodyBytes.toRequestBody(mediaType)
|
|
243
|
+
bodyString != null -> bodyString.toRequestBody(mediaType)
|
|
244
|
+
upperMethod == "POST" || upperMethod == "PUT" || upperMethod == "PATCH" -> "".toRequestBody(null)
|
|
245
|
+
else -> null
|
|
246
|
+
}
|
|
247
|
+
builder.method(upperMethod, body)
|
|
235
248
|
|
|
236
249
|
httpClient.newCall(builder.build()).enqueue(object : Callback {
|
|
237
250
|
override fun onFailure(call: Call, e: IOException) {
|
package/build/Crust.types.d.ts
CHANGED
|
@@ -20,6 +20,12 @@ export type CrustModuleEvents = {
|
|
|
20
20
|
* Without a passcode iOS never protects data, so `unlocked` is always true
|
|
21
21
|
* there and carries no information; check `passcodeSet` first.
|
|
22
22
|
*/
|
|
23
|
+
export type StatusBarFrame = {
|
|
24
|
+
x: number;
|
|
25
|
+
y: number;
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
};
|
|
23
29
|
export type PhoneLockState = {
|
|
24
30
|
unlocked: boolean;
|
|
25
31
|
passcodeSet: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Crust.types.d.ts","sourceRoot":"","sources":["../src/Crust.types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Crust.types.d.ts","sourceRoot":"","sources":["../src/Crust.types.ts"],"names":[],"mappings":"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"}
|
package/build/Crust.types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Crust.types.js","sourceRoot":"","sources":["../src/Crust.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {StyleProp, ViewStyle} from \"react-native\"\n\nexport type OnLoadEventPayload = {\n url: string\n}\n\nexport type CrustModuleEvents = {\n onChange: (params: ChangeEventPayload) => void\n onNavManeuver: (params: NavManeuverPayload) => void\n onNavRerouting: (params: Record<string, never>) => void\n onNavArrived: (params: Record<string, never>) => void\n onNavError: (params: NavErrorPayload) => void\n onNavLocation: (params: NavLocationPayload) => void\n onNavRoute: (params: NavRoutePayload) => void\n onNavOffRoute: (params: NavOffRoutePayload) => void\n onHeading: (params: HeadingPayload) => void\n phone_lock_state: (params: PhoneLockState) => void\n}\n\n/**\n * Whether the user can see the phone right now. iOS derives `unlocked` from\n * protected-data availability, Android from screen on + keyguard hidden.\n * Without a passcode iOS never protects data, so `unlocked` is always true\n * there and carries no information; check `passcodeSet` first.\n */\nexport type PhoneLockState = {\n unlocked: boolean\n passcodeSet: boolean\n}\n\nexport type NavOffRoutePayload = {\n /** Approximate perpendicular distance in meters from the route. */\n offRouteDistanceMeters: number\n}\n\nexport type HeadingPayload = {\n /** Compass heading in degrees, 0 = north, 90 = east. */\n degrees: number\n}\n\nexport type NavRoutePayload = {\n points: Array<{lat: number; lng: number}>\n /**\n * Ordered step list along the route, when supplied by the host. Each\n * step is one navigable segment — typically one straight stretch of\n * road ending in a maneuver. Optional for back-compat with older\n * hosts that only ship the polyline. The SDK's pivot module consumes\n * this to enrich pivots with `fromRoad` / `toRoad` metadata.\n */\n steps?: NavRouteStepPayload[]\n}\n\nexport type NavRouteStepPayload = {\n /** Coordinate where this step begins (== end of the previous step). */\n lat: number\n lng: number\n /**\n * Index into `NavRoutePayload.points[]` where this step starts.\n * Lets consumers correlate step boundaries with polyline geometry.\n */\n routeIndex: number\n /** Name of the road traversed during this step. Null when the engine has no name. */\n road?: string | null\n /**\n * Categorical maneuver performed at the END of this step (i.e. how\n * the user exits this step). Same vocabulary as `NavManeuverPayload.maneuverType`.\n */\n maneuver: string\n /** Length of this step in meters. */\n distanceMeters: number\n}\n\nexport type NavLocationPayload = {\n lat: number\n lng: number\n /** Horizontal accuracy in meters, if reported by the platform. */\n accuracy: number | null\n /** Unix ms timestamp of the fix. */\n timestamp: number\n phone_notification: (event: PhoneNotificationEvent) => void\n phone_notification_dismissed: (event: PhoneNotificationDismissedEvent) => void\n captions_tester_incident: (event: CaptionsTesterIncidentEvent) => void\n}\n\nexport type ChangeEventPayload = {\n value: string\n}\n\nexport type NavManeuverPayload = {\n /**\n * Categorical type of the upcoming maneuver. One of: STRAIGHT,\n * SLIGHT_LEFT, SLIGHT_RIGHT, TURN_LEFT, TURN_RIGHT, SHARP_LEFT,\n * SHARP_RIGHT, U_TURN, ARRIVE.\n */\n maneuverType: string\n /** Distance in meters from the user's current position to that maneuver. -1 if unknown. */\n distanceMeters: number\n /** Road the user is currently on, per the Nav SDK. Null if unavailable. */\n fromRoad?: string | null\n /**\n * Legacy \"next road\" field — historically populated from the same\n * source as `fromRoad` (the current step's road, NOT the road\n * after the upcoming turn). Kept for back-compat. New consumers\n * should read `nextStepRoad` instead.\n */\n toRoad?: string | null\n /**\n * Road the user will be on AFTER the upcoming maneuver, sourced\n * from the Nav SDK's `remainingSteps[0]`. This is the value to\n * show as the \"next street\" headline on the maneuver card. Null\n * when the SDK hasn't surfaced a remaining step yet (final leg,\n * pre-first-NavInfo, etc.).\n */\n nextStepRoad?: string | null\n /** Total remaining distance to final destination, meters. -1 if unknown. */\n distanceToDestinationMeters?: number\n /** Total remaining travel time, seconds. -1 if unknown. */\n timeToDestinationSeconds?: number\n /** Current speed in m/s. Null if unavailable. */\n currentSpeedMps?: number | null\n /** Speed limit on the current road segment in m/s. Null if unknown / not regulated. */\n speedLimitMps?: number | null\n /** Bearing along the route at the user's current position, 0–360. Null if unknown. */\n routeHeadingDeg?: number | null\n}\n\nexport type NavErrorPayload = {\n message: string\n}\n\nexport type InstalledApp = {\n packageName: string\n appName: string\n isBlocked: boolean\n icon: string | null\n}\n\nexport type PhoneNotificationEvent = {\n notificationId: string\n app: string\n title: string\n content: string\n /**\n * Android notification priority: PRIORITY_MIN (-2) through PRIORITY_MAX (2).\n * Derived from the channel importance when the ranking is available, since\n * Notification.priority reads 0 for channel-based notifications.\n */\n priority: number\n timestamp: number\n packageName: string\n}\n\nexport type PhoneNotificationDismissedEvent = {\n notificationKey: string\n packageName: string\n notificationId: string\n}\n\nexport type CaptionsTesterIncidentEvent = {\n action?: string\n timestamp?: number\n failure_code?: string\n failure_message?: string\n test_run_id?: string\n scenario_name?: string\n source?: string\n [key: string]: unknown\n}\n\nexport type CrustViewProps = {\n url: string\n onLoad: (event: {nativeEvent: OnLoadEventPayload}) => void\n style?: StyleProp<ViewStyle>\n}\n\n/** A cookie one of the app's WebViews holds; see `getWebViewCookies`. */\nexport type WebViewCookie = {\n name: string\n value: string\n domain: string\n /** iOS reports this; Android's cookie header has no such flag, so it is always false there. */\n httpOnly: boolean\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Crust.types.js","sourceRoot":"","sources":["../src/Crust.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {StyleProp, ViewStyle} from \"react-native\"\n\nexport type OnLoadEventPayload = {\n url: string\n}\n\nexport type CrustModuleEvents = {\n onChange: (params: ChangeEventPayload) => void\n onNavManeuver: (params: NavManeuverPayload) => void\n onNavRerouting: (params: Record<string, never>) => void\n onNavArrived: (params: Record<string, never>) => void\n onNavError: (params: NavErrorPayload) => void\n onNavLocation: (params: NavLocationPayload) => void\n onNavRoute: (params: NavRoutePayload) => void\n onNavOffRoute: (params: NavOffRoutePayload) => void\n onHeading: (params: HeadingPayload) => void\n phone_lock_state: (params: PhoneLockState) => void\n}\n\n/**\n * Whether the user can see the phone right now. iOS derives `unlocked` from\n * protected-data availability, Android from screen on + keyguard hidden.\n * Without a passcode iOS never protects data, so `unlocked` is always true\n * there and carries no information; check `passcodeSet` first.\n */\nexport type StatusBarFrame = {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport type PhoneLockState = {\n unlocked: boolean\n passcodeSet: boolean\n}\n\nexport type NavOffRoutePayload = {\n /** Approximate perpendicular distance in meters from the route. */\n offRouteDistanceMeters: number\n}\n\nexport type HeadingPayload = {\n /** Compass heading in degrees, 0 = north, 90 = east. */\n degrees: number\n}\n\nexport type NavRoutePayload = {\n points: Array<{lat: number; lng: number}>\n /**\n * Ordered step list along the route, when supplied by the host. Each\n * step is one navigable segment — typically one straight stretch of\n * road ending in a maneuver. Optional for back-compat with older\n * hosts that only ship the polyline. The SDK's pivot module consumes\n * this to enrich pivots with `fromRoad` / `toRoad` metadata.\n */\n steps?: NavRouteStepPayload[]\n}\n\nexport type NavRouteStepPayload = {\n /** Coordinate where this step begins (== end of the previous step). */\n lat: number\n lng: number\n /**\n * Index into `NavRoutePayload.points[]` where this step starts.\n * Lets consumers correlate step boundaries with polyline geometry.\n */\n routeIndex: number\n /** Name of the road traversed during this step. Null when the engine has no name. */\n road?: string | null\n /**\n * Categorical maneuver performed at the END of this step (i.e. how\n * the user exits this step). Same vocabulary as `NavManeuverPayload.maneuverType`.\n */\n maneuver: string\n /** Length of this step in meters. */\n distanceMeters: number\n}\n\nexport type NavLocationPayload = {\n lat: number\n lng: number\n /** Horizontal accuracy in meters, if reported by the platform. */\n accuracy: number | null\n /** Unix ms timestamp of the fix. */\n timestamp: number\n phone_notification: (event: PhoneNotificationEvent) => void\n phone_notification_dismissed: (event: PhoneNotificationDismissedEvent) => void\n captions_tester_incident: (event: CaptionsTesterIncidentEvent) => void\n}\n\nexport type ChangeEventPayload = {\n value: string\n}\n\nexport type NavManeuverPayload = {\n /**\n * Categorical type of the upcoming maneuver. One of: STRAIGHT,\n * SLIGHT_LEFT, SLIGHT_RIGHT, TURN_LEFT, TURN_RIGHT, SHARP_LEFT,\n * SHARP_RIGHT, U_TURN, ARRIVE.\n */\n maneuverType: string\n /** Distance in meters from the user's current position to that maneuver. -1 if unknown. */\n distanceMeters: number\n /** Road the user is currently on, per the Nav SDK. Null if unavailable. */\n fromRoad?: string | null\n /**\n * Legacy \"next road\" field — historically populated from the same\n * source as `fromRoad` (the current step's road, NOT the road\n * after the upcoming turn). Kept for back-compat. New consumers\n * should read `nextStepRoad` instead.\n */\n toRoad?: string | null\n /**\n * Road the user will be on AFTER the upcoming maneuver, sourced\n * from the Nav SDK's `remainingSteps[0]`. This is the value to\n * show as the \"next street\" headline on the maneuver card. Null\n * when the SDK hasn't surfaced a remaining step yet (final leg,\n * pre-first-NavInfo, etc.).\n */\n nextStepRoad?: string | null\n /** Total remaining distance to final destination, meters. -1 if unknown. */\n distanceToDestinationMeters?: number\n /** Total remaining travel time, seconds. -1 if unknown. */\n timeToDestinationSeconds?: number\n /** Current speed in m/s. Null if unavailable. */\n currentSpeedMps?: number | null\n /** Speed limit on the current road segment in m/s. Null if unknown / not regulated. */\n speedLimitMps?: number | null\n /** Bearing along the route at the user's current position, 0–360. Null if unknown. */\n routeHeadingDeg?: number | null\n}\n\nexport type NavErrorPayload = {\n message: string\n}\n\nexport type InstalledApp = {\n packageName: string\n appName: string\n isBlocked: boolean\n icon: string | null\n}\n\nexport type PhoneNotificationEvent = {\n notificationId: string\n app: string\n title: string\n content: string\n /**\n * Android notification priority: PRIORITY_MIN (-2) through PRIORITY_MAX (2).\n * Derived from the channel importance when the ranking is available, since\n * Notification.priority reads 0 for channel-based notifications.\n */\n priority: number\n timestamp: number\n packageName: string\n}\n\nexport type PhoneNotificationDismissedEvent = {\n notificationKey: string\n packageName: string\n notificationId: string\n}\n\nexport type CaptionsTesterIncidentEvent = {\n action?: string\n timestamp?: number\n failure_code?: string\n failure_message?: string\n test_run_id?: string\n scenario_name?: string\n source?: string\n [key: string]: unknown\n}\n\nexport type CrustViewProps = {\n url: string\n onLoad: (event: {nativeEvent: OnLoadEventPayload}) => void\n style?: StyleProp<ViewStyle>\n}\n\n/** A cookie one of the app's WebViews holds; see `getWebViewCookies`. */\nexport type WebViewCookie = {\n name: string\n value: string\n domain: string\n /** iOS reports this; Android's cookie header has no such flag, so it is always false there. */\n httpOnly: boolean\n}\n"]}
|
package/build/CrustModule.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { NativeModule } from "expo";
|
|
2
|
-
import type { CrustModuleEvents, InstalledApp, PhoneLockState, WebViewCookie } from "./Crust.types";
|
|
2
|
+
import type { CrustModuleEvents, InstalledApp, PhoneLockState, StatusBarFrame, WebViewCookie } from "./Crust.types";
|
|
3
3
|
declare class CrustModule extends NativeModule<CrustModuleEvents> {
|
|
4
4
|
PI: number;
|
|
5
5
|
hello(): string;
|
|
6
|
+
/**
|
|
7
|
+
* iOS: the system status bar's frame in screen points. On an iPhone Duo with its
|
|
8
|
+
* status rail the bar runs down the side, and its frame grows under an expanded
|
|
9
|
+
* Dynamic Island. Null on Android and when no window scene is active.
|
|
10
|
+
*/
|
|
11
|
+
statusBarFrame(): Promise<StatusBarFrame | null>;
|
|
6
12
|
setValueAsync(value: string): Promise<void>;
|
|
7
13
|
nativeHttpRequest(method: string, url: string, headers: Record<string, string>, body?: string | null): Promise<{
|
|
8
14
|
status: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CrustModule.d.ts","sourceRoot":"","sources":["../src/CrustModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAsB,MAAM,MAAM,CAAA;AAEtD,OAAO,KAAK,EAAC,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAC,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"CrustModule.d.ts","sourceRoot":"","sources":["../src/CrustModule.ts"],"names":[],"mappings":"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"}
|
package/build/CrustModule.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CrustModule.js","sourceRoot":"","sources":["../src/CrustModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,mBAAmB,EAAC,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"CrustModule.js","sourceRoot":"","sources":["../src/CrustModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,mBAAmB,EAAC,MAAM,MAAM,CAAA;AAgNtD,yDAAyD;AACzD,eAAe,mBAAmB,CAAc,OAAO,CAAC,CAAA","sourcesContent":["import {NativeModule, requireNativeModule} from \"expo\"\n\nimport type {CrustModuleEvents, InstalledApp, PhoneLockState, StatusBarFrame, WebViewCookie} from \"./Crust.types\"\n\ndeclare class CrustModule extends NativeModule<CrustModuleEvents> {\n PI: number\n hello(): string\n /**\n * iOS: the system status bar's frame in screen points. On an iPhone Duo with its\n * status rail the bar runs down the side, and its frame grows under an expanded\n * Dynamic Island. Null on Android and when no window scene is active.\n */\n statusBarFrame(): Promise<StatusBarFrame | null>\n setValueAsync(value: string): Promise<void>\n nativeHttpRequest(\n method: string,\n url: string,\n headers: Record<string, string>,\n body?: string | null,\n ): Promise<{status: number; statusText: string; headers: Record<string, string>; body: string}>\n showAVRoutePicker(tintColor?: string | null): void\n\n /**\n * iOS: configure `preferredScreenEdgesDeferringSystemGestures`. When an\n * edge is deferred, the first swipe across that edge is consumed by the\n * app and the system gesture (Control Center, Notification Center, Home\n * indicator) only fires on a second swipe — i.e. a two-swipe-to-exit UX.\n *\n * Pass `[]` to restore default behavior. Android: no-op (Android has no\n * per-app equivalent; system gestures are configured at the OS level).\n */\n setDeferredSystemGestures(edges: Array<\"top\" | \"bottom\" | \"left\" | \"right\" | \"all\">): Promise<void>\n\n // Glassly Notification Commands\n setNotificationConfig(listenerEnabled: boolean, blocklist: string[]): Promise<void>\n getInstalledApps(): Promise<InstalledApp[]>\n getInstalledAppsForNotifications(): Promise<InstalledApp[]>\n hasNotificationListenerPermission(): Promise<boolean>\n refreshNotificationListener(): Promise<boolean>\n openNotificationListenerSettings(): Promise<boolean>\n /** Current lock state; changes arrive as `phone_lock_state` events. */\n getPhoneLockState(): Promise<PhoneLockState>\n isBetaBuild(): Promise<boolean>\n // location services commands\n showLocationServicesDialog(): Promise<boolean>\n isLocationServicesEnabled(): Promise<boolean>\n openLocationSettings(): Promise<boolean>\n openAppSettings(): Promise<boolean>\n openBluetoothSettings(): Promise<boolean>\n\n /**\n * Cookies the app's WebViews hold for `url`'s host, HttpOnly ones included\n * (a page's own JS cannot read those). Backs `session.system.webLogin`.\n */\n getWebViewCookies(url: string): Promise<WebViewCookie[]>\n /** Deletes those cookies, best effort; resolves with how many it removed. */\n clearWebViewCookies(url: string): Promise<number>\n\n // Image Processing Commands\n processGalleryImage(\n inputPath: string,\n outputPath: string,\n options: {\n lensCorrection?: boolean\n colorCorrection?: boolean\n },\n ): Promise<{\n success: boolean\n outputPath?: string\n processingTimeMs?: number\n error?: string\n }>\n\n mergeHdrBrackets(\n underPath: string,\n normalPath: string,\n overPath: string,\n outputPath: string,\n ): Promise<{\n success: boolean\n outputPath?: string\n processingTimeMs?: number\n error?: string\n }>\n\n stabilizeVideo(\n inputPath: string,\n imuPath: string,\n outputPath: string,\n ): Promise<{\n success: boolean\n outputPath?: string\n processingTimeMs?: number\n error?: string\n }>\n\n // Media Library Commands\n saveToGalleryWithDate(\n filePath: string,\n captureTimeMillis?: number,\n displayName?: string,\n ): Promise<{\n success: boolean\n uri?: string\n identifier?: string\n existing?: boolean\n error?: string\n }>\n\n // Navigation (both platforms via Mapbox; the dev toggles below are Android-only)\n /**\n * Override the Mapbox access token the native Navigation SDK\n * authenticates with. A non-empty token wins over the one baked at build\n * time (AndroidManifest `com.mapbox.token` / Info.plist `MBXAccessToken`);\n * \"\" clears the override and restores the baked token. Call before\n * `startNavigation` — the engine pushes the user's Settings > Keys token\n * here per trip start.\n */\n setMapboxAccessToken(token: string): Promise<{ok: boolean; error?: string}>\n startNavigation(\n lat: number,\n lng: number,\n options?: {\n simulate?: boolean\n speedMultiplier?: number\n /** Optional multi-stop list. When present takes precedence over lat/lng. Last entry is the final destination. */\n stops?: Array<{lat: number; lng: number}>\n /** \"walking\" | \"driving\" | \"cycling\" | \"two_wheeler\". Defaults driving. */\n mode?: string\n avoid?: {highways?: boolean; tolls?: boolean; ferries?: boolean}\n /** Force a reroute when the user is more than N meters past a pivot they didn't take. */\n missedTurnRerouteMeters?: number\n },\n ): Promise<{ok: boolean; error?: string}>\n stopNavigation(): Promise<{ok: boolean; error?: string}>\n\n /**\n * Kept for API parity with the Google-era contract. Mapbox has no\n * Terms & Conditions dialog, so no dialog is shown; resolves with\n * `{accepted: true}` once permission handling completes. Idempotent —\n * still safe (and intended) to call eagerly.\n */\n requestNavigationPermission(): Promise<{ok: boolean; accepted: boolean; error?: string}>\n\n /**\n * Dev-only: push the simulated user position off-route so the Nav SDK\n * reroutes. Only meaningful in simulate mode. Both platforms;\n * `offsetMeters` tunes the jump on Android and is ignored on iOS.\n */\n simulateDeviation(offsetMeters?: number): Promise<{ok: boolean; error?: string}>\n\n /**\n * Dev toggle. When enabled, the native NavigationManager shifts every\n * reported location ~8m perpendicular to the route bearing, simulating\n * a pedestrian walking on the wrong sidewalk. Only meaningful in\n * simulate mode; lets us verify the SDK's along-path pivot trigger\n * fires even when the user never crosses the 7m pivot point radius.\n * Android-only today; iOS is a no-op stub.\n */\n setWrongSidewalkOffset(enabled: boolean): Promise<{ok: boolean; error?: string}>\n\n /**\n * Dev toggle. When enabled, the native NavigationManager takes over\n * from the Mapbox simulator and walks the user along a modified\n * polyline that omits crossing micro-steps — reproducing the\n * wrong-sidewalk-then-missed-the-turn scenario. Android-only today;\n * iOS is a no-op stub.\n */\n setSkipCrossings(enabled: boolean): Promise<{ok: boolean; error?: string}>\n\n // Heading / compass (both platforms)\n startHeading(): Promise<{ok: boolean; error?: string}>\n stopHeading(): Promise<{ok: boolean; error?: string}>\n\n // JS Runtime — per-miniapp JSContext lifecycle.\n /**\n * Spawn a per-miniapp JS context. Re-spawn is allowed: a live context\n * with the same packageName is killed first. Returns true if the\n * polyfill bundle + miniapp source evaluated without throwing.\n *\n * The polyfill bundle is `mobile/modules/jspolyfill/dist/startup.js`\n * (shipped inside the host binary). It installs window-style globals\n * (console, timers, fetch, localStorage, crypto) atop the JSC runtime.\n */\n jsSpawn(packageName: string, polyfillBundle: string, miniappJs: string): Promise<boolean>\n jsEvaluate(packageName: string, source: string): Promise<unknown>\n jsKill(packageName: string): Promise<void>\n /**\n * Push a `{kind: \"event\"|\"response\", …}` envelope into the named\n * context's globalThis.__deliver. Returns when the underlying\n * evaluateScript completes (the JS handler runs synchronously on the\n * context's queue).\n */\n jsDispatchToJs(packageName: string, envelope: Record<string, unknown>): Promise<void>\n jsSetManifest(packageName: string, permissions: string[]): Promise<void>\n /** Diagnostic — returns the packageNames of every live JSContext. */\n jsAlivePackages(): string[]\n /** Diagnostic — force a GC cycle on the named context. */\n jsDebugForceGC(packageName: string): Promise<boolean>\n /**\n * Read the bundled JSRuntime polyfill (startup.js) shipped inside the\n * host binary. Synchronous — host RN code calls this once on app boot\n * and caches the string, then passes it to every jsSpawn so\n * every JSContext starts with the same polyfill ABI.\n */\n jsLoadPolyfillBundle(): string\n}\n\n// This call loads the native module object from the JSI.\nexport default requireNativeModule<CrustModule>(\"Crust\")\n"]}
|
|
@@ -12,6 +12,7 @@ declare class CrustModule extends NativeModule<CrustModuleEvents> {
|
|
|
12
12
|
body: string;
|
|
13
13
|
}>;
|
|
14
14
|
hello(): string;
|
|
15
|
+
statusBarFrame(): Promise<null>;
|
|
15
16
|
showAVRoutePicker(_tintColor?: string | null): void;
|
|
16
17
|
setDeferredSystemGestures(_edges: string[]): Promise<void>;
|
|
17
18
|
setNotificationConfig(_listenerEnabled: boolean, _blocklist: string[]): Promise<void>;
|
|
@@ -40,6 +41,6 @@ declare class CrustModule extends NativeModule<CrustModuleEvents> {
|
|
|
40
41
|
jsDebugForceGC(_pkg: string): Promise<boolean>;
|
|
41
42
|
jsLoadPolyfillBundle(): string;
|
|
42
43
|
}
|
|
43
|
-
declare const _default:
|
|
44
|
+
declare const _default: CrustModule;
|
|
44
45
|
export default _default;
|
|
45
46
|
//# sourceMappingURL=CrustModule.web.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CrustModule.web.d.ts","sourceRoot":"","sources":["../src/CrustModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,YAAY,EAAC,MAAM,MAAM,CAAA;AAEpD,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAA;AAEpD,cAAM,WAAY,SAAQ,YAAY,CAAC,iBAAiB,CAAC;IACvD,EAAE,SAAU;IACN,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAG3C,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;;;;;;;;IAS1G,KAAK;
|
|
1
|
+
{"version":3,"file":"CrustModule.web.d.ts","sourceRoot":"","sources":["../src/CrustModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,YAAY,EAAC,MAAM,MAAM,CAAA;AAEpD,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAA;AAEpD,cAAM,WAAY,SAAQ,YAAY,CAAC,iBAAiB,CAAC;IACvD,EAAE,SAAU;IACN,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAG3C,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;;;;;;;;IAS1G,KAAK;IAGC,cAAc;IAGpB,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IACtC,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1D,qBAAqB,CAAC,gBAAgB,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IACrF,gBAAgB;IAGhB,gCAAgC;IAGhC,iCAAiC;IAGjC,2BAA2B;IAG3B,gCAAgC;IAGhC,iBAAiB;;;;IAGjB,WAAW;IAGX,iBAAiB,CAAC,IAAI,EAAE,MAAM;IAG9B,mBAAmB,CAAC,IAAI,EAAE,MAAM;IAGhC,oBAAoB,CAAC,MAAM,EAAE,MAAM;;;;IAGnC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAG3D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAGrC,MAAM,CAAC,IAAI,EAAE,MAAM;IAGnB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAG1D,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;IAGlD,eAAe;IAGT,cAAc,CAAC,IAAI,EAAE,MAAM;IAGjC,oBAAoB;CAGrB;;AAED,wBAA4D"}
|
package/build/CrustModule.web.js
CHANGED
|
@@ -16,6 +16,9 @@ class CrustModule extends NativeModule {
|
|
|
16
16
|
hello() {
|
|
17
17
|
return "Hello world! 👋";
|
|
18
18
|
}
|
|
19
|
+
async statusBarFrame() {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
19
22
|
showAVRoutePicker(_tintColor) { }
|
|
20
23
|
async setDeferredSystemGestures(_edges) { }
|
|
21
24
|
async setNotificationConfig(_listenerEnabled, _blocklist) { }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CrustModule.web.js","sourceRoot":"","sources":["../src/CrustModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAE,YAAY,EAAC,MAAM,MAAM,CAAA;AAIpD,MAAM,WAAY,SAAQ,YAA+B;IACvD,EAAE,GAAG,IAAI,CAAC,EAAE,CAAA;IACZ,KAAK,CAAC,aAAa,CAAC,KAAa;QAC/B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAC,KAAK,EAAC,CAAC,CAAA;IAChC,CAAC;IACD,KAAK,CAAC,iBAAiB,CAAC,MAAc,EAAE,GAAW,EAAE,OAA+B,EAAE,IAAoB;QACxG,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC,CAAA;QAC1D,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACvD,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE;SAC5B,CAAA;IACH,CAAC;IACD,KAAK;QACH,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IACD,iBAAiB,CAAC,UAA0B,IAAG,CAAC;IAChD,KAAK,CAAC,yBAAyB,CAAC,MAAgB,IAAkB,CAAC;IACnE,KAAK,CAAC,qBAAqB,CAAC,gBAAyB,EAAE,UAAoB,IAAkB,CAAC;IAC9F,KAAK,CAAC,gBAAgB;QACpB,OAAO,EAAE,CAAA;IACX,CAAC;IACD,KAAK,CAAC,gCAAgC;QACpC,OAAO,EAAE,CAAA;IACX,CAAC;IACD,KAAK,CAAC,iCAAiC;QACrC,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,CAAC,2BAA2B;QAC/B,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,CAAC,gCAAgC;QACpC,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,CAAC,iBAAiB;QACrB,OAAO,EAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAC,CAAA;IAC7C,CAAC;IACD,KAAK,CAAC,WAAW;QACf,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,CAAC,iBAAiB,CAAC,IAAY;QAClC,OAAO,EAAE,CAAA;IACX,CAAC;IACD,KAAK,CAAC,mBAAmB,CAAC,IAAY;QACpC,OAAO,CAAC,CAAA;IACV,CAAC;IACD,KAAK,CAAC,oBAAoB,CAAC,MAAc;QACvC,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAC,CAAA;IACnD,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,SAAiB,EAAE,UAAkB;QAC/D,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,IAAY;QACzC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,OAAM;IACR,CAAC;IACD,KAAK,CAAC,cAAc,CAAC,IAAY,EAAE,IAA6B;QAC9D,OAAM;IACR,CAAC;IACD,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,MAAgB;QAChD,OAAM;IACR,CAAC;IACD,eAAe;QACb,OAAO,EAAE,CAAA;IACX,CAAC;IACD,KAAK,CAAC,cAAc,CAAC,IAAY;QAC/B,OAAO,KAAK,CAAA;IACd,CAAC;IACD,oBAAoB;QAClB,OAAO,EAAE,CAAA;IACX,CAAC;CACF;AAED,eAAe,iBAAiB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAA","sourcesContent":["import {registerWebModule, NativeModule} from \"expo\"\n\nimport type {CrustModuleEvents} from \"./Crust.types\"\n\nclass CrustModule extends NativeModule<CrustModuleEvents> {\n PI = Math.PI\n async setValueAsync(value: string): Promise<void> {\n this.emit(\"onChange\", {value})\n }\n async nativeHttpRequest(method: string, url: string, headers: Record<string, string>, body?: string | null) {\n const response = await fetch(url, {method, headers, body})\n return {\n status: response.status,\n statusText: response.statusText,\n headers: Object.fromEntries(response.headers.entries()),\n body: await response.text(),\n }\n }\n hello() {\n return \"Hello world! 👋\"\n }\n showAVRoutePicker(_tintColor?: string | null) {}\n async setDeferredSystemGestures(_edges: string[]): Promise<void> {}\n async setNotificationConfig(_listenerEnabled: boolean, _blocklist: string[]): Promise<void> {}\n async getInstalledApps() {\n return []\n }\n async getInstalledAppsForNotifications() {\n return []\n }\n async hasNotificationListenerPermission() {\n return false\n }\n async refreshNotificationListener() {\n return false\n }\n async openNotificationListenerSettings() {\n return false\n }\n async getPhoneLockState() {\n return {unlocked: true, passcodeSet: false}\n }\n async isBetaBuild() {\n return false\n }\n async getWebViewCookies(_url: string) {\n return []\n }\n async clearWebViewCookies(_url: string) {\n return 0\n }\n async setMapboxAccessToken(_token: string) {\n return {ok: false, error: \"Not supported on web\"}\n }\n async jsSpawn(_pkg: string, _polyfill: string, _miniappJs: string) {\n return false\n }\n async jsEvaluate(_pkg: string, _src: string) {\n return null\n }\n async jsKill(_pkg: string) {\n return\n }\n async jsDispatchToJs(_pkg: string, _env: Record<string, unknown>) {\n return\n }\n async jsSetManifest(_pkg: string, _perms: string[]) {\n return\n }\n jsAlivePackages() {\n return []\n }\n async jsDebugForceGC(_pkg: string) {\n return false\n }\n jsLoadPolyfillBundle() {\n return \"\"\n }\n}\n\nexport default registerWebModule(CrustModule, \"CrustModule\")\n"]}
|
|
1
|
+
{"version":3,"file":"CrustModule.web.js","sourceRoot":"","sources":["../src/CrustModule.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAE,YAAY,EAAC,MAAM,MAAM,CAAA;AAIpD,MAAM,WAAY,SAAQ,YAA+B;IACvD,EAAE,GAAG,IAAI,CAAC,EAAE,CAAA;IACZ,KAAK,CAAC,aAAa,CAAC,KAAa;QAC/B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAC,KAAK,EAAC,CAAC,CAAA;IAChC,CAAC;IACD,KAAK,CAAC,iBAAiB,CAAC,MAAc,EAAE,GAAW,EAAE,OAA+B,EAAE,IAAoB;QACxG,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC,CAAA;QAC1D,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACvD,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE;SAC5B,CAAA;IACH,CAAC;IACD,KAAK;QACH,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IACD,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,iBAAiB,CAAC,UAA0B,IAAG,CAAC;IAChD,KAAK,CAAC,yBAAyB,CAAC,MAAgB,IAAkB,CAAC;IACnE,KAAK,CAAC,qBAAqB,CAAC,gBAAyB,EAAE,UAAoB,IAAkB,CAAC;IAC9F,KAAK,CAAC,gBAAgB;QACpB,OAAO,EAAE,CAAA;IACX,CAAC;IACD,KAAK,CAAC,gCAAgC;QACpC,OAAO,EAAE,CAAA;IACX,CAAC;IACD,KAAK,CAAC,iCAAiC;QACrC,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,CAAC,2BAA2B;QAC/B,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,CAAC,gCAAgC;QACpC,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,CAAC,iBAAiB;QACrB,OAAO,EAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAC,CAAA;IAC7C,CAAC;IACD,KAAK,CAAC,WAAW;QACf,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,CAAC,iBAAiB,CAAC,IAAY;QAClC,OAAO,EAAE,CAAA;IACX,CAAC;IACD,KAAK,CAAC,mBAAmB,CAAC,IAAY;QACpC,OAAO,CAAC,CAAA;IACV,CAAC;IACD,KAAK,CAAC,oBAAoB,CAAC,MAAc;QACvC,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAC,CAAA;IACnD,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,SAAiB,EAAE,UAAkB;QAC/D,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,IAAY;QACzC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,OAAM;IACR,CAAC;IACD,KAAK,CAAC,cAAc,CAAC,IAAY,EAAE,IAA6B;QAC9D,OAAM;IACR,CAAC;IACD,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,MAAgB;QAChD,OAAM;IACR,CAAC;IACD,eAAe;QACb,OAAO,EAAE,CAAA;IACX,CAAC;IACD,KAAK,CAAC,cAAc,CAAC,IAAY;QAC/B,OAAO,KAAK,CAAA;IACd,CAAC;IACD,oBAAoB;QAClB,OAAO,EAAE,CAAA;IACX,CAAC;CACF;AAED,eAAe,iBAAiB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAA","sourcesContent":["import {registerWebModule, NativeModule} from \"expo\"\n\nimport type {CrustModuleEvents} from \"./Crust.types\"\n\nclass CrustModule extends NativeModule<CrustModuleEvents> {\n PI = Math.PI\n async setValueAsync(value: string): Promise<void> {\n this.emit(\"onChange\", {value})\n }\n async nativeHttpRequest(method: string, url: string, headers: Record<string, string>, body?: string | null) {\n const response = await fetch(url, {method, headers, body})\n return {\n status: response.status,\n statusText: response.statusText,\n headers: Object.fromEntries(response.headers.entries()),\n body: await response.text(),\n }\n }\n hello() {\n return \"Hello world! 👋\"\n }\n async statusBarFrame() {\n return null\n }\n showAVRoutePicker(_tintColor?: string | null) {}\n async setDeferredSystemGestures(_edges: string[]): Promise<void> {}\n async setNotificationConfig(_listenerEnabled: boolean, _blocklist: string[]): Promise<void> {}\n async getInstalledApps() {\n return []\n }\n async getInstalledAppsForNotifications() {\n return []\n }\n async hasNotificationListenerPermission() {\n return false\n }\n async refreshNotificationListener() {\n return false\n }\n async openNotificationListenerSettings() {\n return false\n }\n async getPhoneLockState() {\n return {unlocked: true, passcodeSet: false}\n }\n async isBetaBuild() {\n return false\n }\n async getWebViewCookies(_url: string) {\n return []\n }\n async clearWebViewCookies(_url: string) {\n return 0\n }\n async setMapboxAccessToken(_token: string) {\n return {ok: false, error: \"Not supported on web\"}\n }\n async jsSpawn(_pkg: string, _polyfill: string, _miniappJs: string) {\n return false\n }\n async jsEvaluate(_pkg: string, _src: string) {\n return null\n }\n async jsKill(_pkg: string) {\n return\n }\n async jsDispatchToJs(_pkg: string, _env: Record<string, unknown>) {\n return\n }\n async jsSetManifest(_pkg: string, _perms: string[]) {\n return\n }\n jsAlivePackages() {\n return []\n }\n async jsDebugForceGC(_pkg: string) {\n return false\n }\n jsLoadPolyfillBundle() {\n return \"\"\n }\n}\n\nexport default registerWebModule(CrustModule, \"CrustModule\")\n"]}
|
package/ios/CrustModule.swift
CHANGED
|
@@ -77,6 +77,20 @@ public class CrustModule: Module {
|
|
|
77
77
|
return ["unlocked": unlocked, "passcodeSet": passcodeSet]
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
/// The status bar's frame in screen points, read on the main queue; nil without an active window scene.
|
|
81
|
+
private static func currentStatusBarFrame() -> [String: Double]? {
|
|
82
|
+
let scenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }
|
|
83
|
+
let active = scenes.first { $0.activationState == .foregroundActive }
|
|
84
|
+
guard let scene = active ?? scenes.first, let manager = scene.statusBarManager else { return nil }
|
|
85
|
+
let frame = manager.statusBarFrame
|
|
86
|
+
return [
|
|
87
|
+
"x": Double(frame.origin.x),
|
|
88
|
+
"y": Double(frame.origin.y),
|
|
89
|
+
"width": Double(frame.size.width),
|
|
90
|
+
"height": Double(frame.size.height),
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
|
|
80
94
|
public func definition() -> ModuleDefinition {
|
|
81
95
|
Name("Crust")
|
|
82
96
|
|
|
@@ -145,6 +159,10 @@ public class CrustModule: Module {
|
|
|
145
159
|
"Hello world! 👋"
|
|
146
160
|
}
|
|
147
161
|
|
|
162
|
+
AsyncFunction("statusBarFrame") { () -> [String: Double]? in
|
|
163
|
+
Self.currentStatusBarFrame()
|
|
164
|
+
}.runOnQueue(.main)
|
|
165
|
+
|
|
148
166
|
AsyncFunction("setValueAsync") { (value: String) in
|
|
149
167
|
self.sendEvent("onChange", [
|
|
150
168
|
"value": value,
|
package/ios/Resources/startup.js
CHANGED
|
@@ -254,9 +254,16 @@
|
|
|
254
254
|
let env;
|
|
255
255
|
try {
|
|
256
256
|
env = JSON.parse(envelopeJson);
|
|
257
|
-
} catch {
|
|
257
|
+
} catch (e) {
|
|
258
258
|
try {
|
|
259
|
-
|
|
259
|
+
const reason = e instanceof Error ? `${e.name}: ${e.message}` : String(e);
|
|
260
|
+
const length = typeof envelopeJson === "string" ? envelopeJson.length : -1;
|
|
261
|
+
__hostError(
|
|
262
|
+
JSON.stringify({
|
|
263
|
+
message: `Bad __deliver envelope JSON (${reason}; length=${length}, type=${typeof envelopeJson})`,
|
|
264
|
+
source: "__deliver"
|
|
265
|
+
})
|
|
266
|
+
);
|
|
260
267
|
} catch {
|
|
261
268
|
}
|
|
262
269
|
return;
|
|
@@ -546,15 +553,36 @@
|
|
|
546
553
|
return out;
|
|
547
554
|
};
|
|
548
555
|
}
|
|
556
|
+
function bytesToBase64(bytes) {
|
|
557
|
+
const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
558
|
+
let out = "";
|
|
559
|
+
let i = 0;
|
|
560
|
+
while (i < bytes.length) {
|
|
561
|
+
const c1 = bytes[i++];
|
|
562
|
+
const c2 = i < bytes.length ? bytes[i++] : NaN;
|
|
563
|
+
const c3 = i < bytes.length ? bytes[i++] : NaN;
|
|
564
|
+
const e1 = c1 >> 2;
|
|
565
|
+
const e2 = (c1 & 3) << 4 | (Number.isNaN(c2) ? 0 : c2 >> 4);
|
|
566
|
+
const e3 = Number.isNaN(c2) ? 64 : (c2 & 15) << 2 | (Number.isNaN(c3) ? 0 : c3 >> 6);
|
|
567
|
+
const e4 = Number.isNaN(c3) ? 64 : c3 & 63;
|
|
568
|
+
out += b64[e1] + b64[e2] + (e3 === 64 ? "=" : b64[e3]) + (e4 === 64 ? "=" : b64[e4]);
|
|
569
|
+
}
|
|
570
|
+
return out;
|
|
571
|
+
}
|
|
549
572
|
if (typeof g.fetch !== "function") {
|
|
550
573
|
;
|
|
551
574
|
g.fetch = async (input, init) => {
|
|
552
575
|
const url = typeof input === "string" ? input : input.toString();
|
|
553
576
|
const method = (init?.method ?? "GET").toUpperCase();
|
|
554
577
|
let bodyString = null;
|
|
578
|
+
let bodyBase64 = null;
|
|
555
579
|
const reqBody = init?.body;
|
|
556
580
|
if (typeof reqBody === "string") {
|
|
557
581
|
bodyString = reqBody;
|
|
582
|
+
} else if (reqBody instanceof ArrayBuffer) {
|
|
583
|
+
bodyBase64 = bytesToBase64(new Uint8Array(reqBody));
|
|
584
|
+
} else if (ArrayBuffer.isView(reqBody)) {
|
|
585
|
+
bodyBase64 = bytesToBase64(new Uint8Array(reqBody.buffer, reqBody.byteOffset, reqBody.byteLength));
|
|
558
586
|
} else if (reqBody && typeof reqBody.toString === "function") {
|
|
559
587
|
bodyString = reqBody.toString();
|
|
560
588
|
}
|
|
@@ -577,7 +605,7 @@
|
|
|
577
605
|
}
|
|
578
606
|
}
|
|
579
607
|
const sendRequest = g.__sendRequest;
|
|
580
|
-
const result = await sendRequest("fetch", "request", [{ url, method, headers, body: bodyString }]);
|
|
608
|
+
const result = await sendRequest("fetch", "request", [{ url, method, headers, body: bodyString, bodyBase64 }]);
|
|
581
609
|
const bodyText = typeof result.body === "string" ? result.body : "";
|
|
582
610
|
const responseHeaders = new Map(Object.entries(result.headers ?? {}));
|
|
583
611
|
class ResponseLike {
|
|
@@ -617,22 +645,7 @@
|
|
|
617
645
|
};
|
|
618
646
|
}
|
|
619
647
|
if (typeof g.WebSocket !== "function") {
|
|
620
|
-
let
|
|
621
|
-
const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
622
|
-
let out = "";
|
|
623
|
-
let i = 0;
|
|
624
|
-
while (i < bytes.length) {
|
|
625
|
-
const c1 = bytes[i++];
|
|
626
|
-
const c2 = i < bytes.length ? bytes[i++] : NaN;
|
|
627
|
-
const c3 = i < bytes.length ? bytes[i++] : NaN;
|
|
628
|
-
const e1 = c1 >> 2;
|
|
629
|
-
const e2 = (c1 & 3) << 4 | (Number.isNaN(c2) ? 0 : c2 >> 4);
|
|
630
|
-
const e3 = Number.isNaN(c2) ? 64 : (c2 & 15) << 2 | (Number.isNaN(c3) ? 0 : c3 >> 6);
|
|
631
|
-
const e4 = Number.isNaN(c3) ? 64 : c3 & 63;
|
|
632
|
-
out += b64[e1] + b64[e2] + (e3 === 64 ? "=" : b64[e3]) + (e4 === 64 ? "=" : b64[e4]);
|
|
633
|
-
}
|
|
634
|
-
return out;
|
|
635
|
-
}, base64ToBytes2 = function(s) {
|
|
648
|
+
let base64ToBytes2 = function(s) {
|
|
636
649
|
const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
637
650
|
const clean = s.replace(/=+$/, "");
|
|
638
651
|
const out = [];
|
|
@@ -654,7 +667,7 @@
|
|
|
654
667
|
if (typeof q === "function") q(fn);
|
|
655
668
|
else g.Promise.resolve().then(fn);
|
|
656
669
|
};
|
|
657
|
-
var
|
|
670
|
+
var base64ToBytes = base64ToBytes2, queueMicrotaskSafe = queueMicrotaskSafe2;
|
|
658
671
|
const sockets = /* @__PURE__ */ new Map();
|
|
659
672
|
g.__deliverWebSocketEvent = (sid, type, payload) => {
|
|
660
673
|
const sock = sockets.get(sid);
|
|
@@ -713,7 +726,7 @@
|
|
|
713
726
|
} else {
|
|
714
727
|
kind = "binary";
|
|
715
728
|
const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
716
|
-
payload =
|
|
729
|
+
payload = bytesToBase64(bytes);
|
|
717
730
|
}
|
|
718
731
|
try {
|
|
719
732
|
__dispatch("ws", "send", JSON.stringify([{ sid: this.sid, kind, payload }]));
|
|
@@ -100,14 +100,25 @@ public enum JSCPolyfillBridge {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
var urlRequest = URLRequest(url: url)
|
|
103
|
-
|
|
103
|
+
let method = (req["method"] as? String) ?? "GET"
|
|
104
|
+
urlRequest.httpMethod = method
|
|
104
105
|
if let headers = req["headers"] as? [String: Any] {
|
|
105
106
|
for (k, v) in headers {
|
|
106
107
|
urlRequest.setValue(String(describing: v), forHTTPHeaderField: k)
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
let upperMethod = method.uppercased()
|
|
111
|
+
if upperMethod == "GET" || upperMethod == "HEAD" {
|
|
112
|
+
urlRequest.httpBody = nil
|
|
113
|
+
} else if let encoded = req["bodyBase64"] as? String {
|
|
114
|
+
guard let data = Data(base64Encoded: encoded) else {
|
|
115
|
+
return .error(code: "INVALID_ARGS", message: "fetch.request: bodyBase64 is not base64")
|
|
116
|
+
}
|
|
117
|
+
urlRequest.httpBody = data
|
|
118
|
+
} else if let body = req["body"] as? String {
|
|
119
|
+
urlRequest.httpBody = Data(body.utf8)
|
|
120
|
+
} else if ["POST", "PUT", "PATCH"].contains(upperMethod) {
|
|
121
|
+
urlRequest.httpBody = Data()
|
|
111
122
|
}
|
|
112
123
|
|
|
113
124
|
// Reasonable defaults — caller can override later by passing
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glassly/crust",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6-dev.846",
|
|
4
4
|
"description": "Glassly Native Module",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"homepage": "https://github.com/fossephate/crust#readme",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@glassly/jspolyfill": "0.3.
|
|
38
|
+
"@glassly/jspolyfill": "0.3.6-dev.846"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@expo/config-plugins": ">=8.0.0",
|
package/src/Crust.types.ts
CHANGED
|
@@ -23,6 +23,13 @@ export type CrustModuleEvents = {
|
|
|
23
23
|
* Without a passcode iOS never protects data, so `unlocked` is always true
|
|
24
24
|
* there and carries no information; check `passcodeSet` first.
|
|
25
25
|
*/
|
|
26
|
+
export type StatusBarFrame = {
|
|
27
|
+
x: number
|
|
28
|
+
y: number
|
|
29
|
+
width: number
|
|
30
|
+
height: number
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
export type PhoneLockState = {
|
|
27
34
|
unlocked: boolean
|
|
28
35
|
passcodeSet: boolean
|
package/src/CrustModule.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import {NativeModule, requireNativeModule} from "expo"
|
|
2
2
|
|
|
3
|
-
import type {CrustModuleEvents, InstalledApp, PhoneLockState, WebViewCookie} from "./Crust.types"
|
|
3
|
+
import type {CrustModuleEvents, InstalledApp, PhoneLockState, StatusBarFrame, WebViewCookie} from "./Crust.types"
|
|
4
4
|
|
|
5
5
|
declare class CrustModule extends NativeModule<CrustModuleEvents> {
|
|
6
6
|
PI: number
|
|
7
7
|
hello(): string
|
|
8
|
+
/**
|
|
9
|
+
* iOS: the system status bar's frame in screen points. On an iPhone Duo with its
|
|
10
|
+
* status rail the bar runs down the side, and its frame grows under an expanded
|
|
11
|
+
* Dynamic Island. Null on Android and when no window scene is active.
|
|
12
|
+
*/
|
|
13
|
+
statusBarFrame(): Promise<StatusBarFrame | null>
|
|
8
14
|
setValueAsync(value: string): Promise<void>
|
|
9
15
|
nativeHttpRequest(
|
|
10
16
|
method: string,
|
package/src/CrustModule.web.ts
CHANGED
|
@@ -19,6 +19,9 @@ class CrustModule extends NativeModule<CrustModuleEvents> {
|
|
|
19
19
|
hello() {
|
|
20
20
|
return "Hello world! 👋"
|
|
21
21
|
}
|
|
22
|
+
async statusBarFrame() {
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
22
25
|
showAVRoutePicker(_tintColor?: string | null) {}
|
|
23
26
|
async setDeferredSystemGestures(_edges: string[]): Promise<void> {}
|
|
24
27
|
async setNotificationConfig(_listenerEnabled: boolean, _blocklist: string[]): Promise<void> {}
|