@absolutejs/absolute 0.20.0-beta.93 → 0.20.0-beta.94

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/CHANGELOG.md CHANGED
@@ -6,6 +6,18 @@ This file is generated by `absolute-changelog` from the entries in
6
6
  `changelog/`. Edit an entry, not this file — and add new ones under
7
7
  `changelog/unreleased/`.
8
8
 
9
+ ## 0.20.0-beta.94 — 2026-09-15
10
+
11
+ ### Added
12
+
13
+ - **Expo Android restores in-flight camera results after background process death** (`ABSOLUTE_EXPO_BRIDGE_METHODS`, `parseAbsoluteExpoBridgeMessage`)
14
+ Generated Expo shells expose the provider-neutral restored-operation queue through the allowlisted bridge, and an installed API 36 gate proves exactly-once camera recovery without leaking native file paths.
15
+
16
+ ### Fixed
17
+
18
+ - **WSL Expo Android rebuilds preserve a compatible Windows Bun lockfile until source dependencies change**
19
+ AbsoluteJS hashes the source lock input and invalidates the mirrored Windows lock only when dependencies change, avoiding repeated resolution while keeping each host Bun version in control of its own lock format.
20
+
9
21
  ## 0.20.0-beta.93 — 2026-09-13
10
22
 
11
23
  ### Added
package/changelog.json CHANGED
@@ -2,6 +2,26 @@
2
2
  "contract": 1,
3
3
  "name": "@absolutejs/absolute",
4
4
  "releases": [
5
+ {
6
+ "changes": [
7
+ {
8
+ "detail": "Generated Expo shells expose the provider-neutral restored-operation queue through the allowlisted bridge, and an installed API 36 gate proves exactly-once camera recovery without leaking native file paths.",
9
+ "kind": "added",
10
+ "summary": "Expo Android restores in-flight camera results after background process death",
11
+ "symbols": [
12
+ "ABSOLUTE_EXPO_BRIDGE_METHODS",
13
+ "parseAbsoluteExpoBridgeMessage"
14
+ ]
15
+ },
16
+ {
17
+ "detail": "AbsoluteJS hashes the source lock input and invalidates the mirrored Windows lock only when dependencies change, avoiding repeated resolution while keeping each host Bun version in control of its own lock format.",
18
+ "kind": "fixed",
19
+ "summary": "WSL Expo Android rebuilds preserve a compatible Windows Bun lockfile until source dependencies change"
20
+ }
21
+ ],
22
+ "date": "2026-09-15",
23
+ "version": "0.20.0-beta.94"
24
+ },
5
25
  {
6
26
  "changes": [
7
27
  {
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  var __require = import.meta.require;
3
3
 
4
- // .angular-partial-tmp-SWiKxc/src/core/streamingSlotRegistrar.ts
4
+ // .angular-partial-tmp-LcQpR5/src/core/streamingSlotRegistrar.ts
5
5
  var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
6
6
  var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
7
7
  var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  var __require = import.meta.require;
3
3
 
4
- // .angular-partial-tmp-SWiKxc/src/core/streamingSlotRegistrar.ts
4
+ // .angular-partial-tmp-LcQpR5/src/core/streamingSlotRegistrar.ts
5
5
  var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
6
6
  var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
7
7
  var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
@@ -48,7 +48,7 @@ var warnMissingStreamingSlotCollector = (primitiveName) => {
48
48
  getWarningController()?.maybeWarn(primitiveName);
49
49
  };
50
50
 
51
- // .angular-partial-tmp-SWiKxc/src/core/streamingSlotRegistry.ts
51
+ // .angular-partial-tmp-LcQpR5/src/core/streamingSlotRegistry.ts
52
52
  var STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
53
53
  var isObjectRecord2 = (value) => Boolean(value) && typeof value === "object";
54
54
  var isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
@@ -15,7 +15,7 @@ import {
15
15
  createIslandRegistryDefinitionPlugin,
16
16
  finalizeAbsoluteMobileCompatibilityBuild,
17
17
  resolveServerBundleExternals
18
- } from "./index-kh44yx23.js";
18
+ } from "./index-d8va9b7v.js";
19
19
  import {
20
20
  loadIslandRegistryBuildInfo
21
21
  } from "./index-bzs19w3r.js";
@@ -36,7 +36,7 @@ import"./index-w5vswatm.js";
36
36
  import {
37
37
  normalizeAbsoluteMobileConfig
38
38
  } from "./index-rd2hbttb.js";
39
- import"./index-wqhbxtyp.js";
39
+ import"./index-0t1cxstr.js";
40
40
  import {
41
41
  ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV,
42
42
  installAbsoluteMobileAuthEnvironment
@@ -1286,8 +1286,8 @@ var loadAbsoluteMobileDevModules = async () => {
1286
1286
  expoNativeWatcher
1287
1287
  ] = await Promise.all([
1288
1288
  import("./config-vy04mqce.js"),
1289
- import("./expoProject-mmm3s62b.js"),
1290
- import("./expoDevController-k15hftqn.js"),
1289
+ import("./expoProject-h38entbj.js"),
1290
+ import("./expoDevController-a0jk8d43.js"),
1291
1291
  import("./nativeAuth-zx4tsb1f.js"),
1292
1292
  import("./androidEmulatorController-nybhzc6c.js"),
1293
1293
  import("./emulatorDoctor-y2nqmaha.js"),
@@ -208,10 +208,15 @@ var encodedWindowsExpoAndroidCommand = (project, androidRoot, appId, args, captu
208
208
  `$env:NODE_ENV = '${mode === "development" ? "development" : "production"}'`,
209
209
  ...preferredDevice ? [] : ["$env:ORG_GRADLE_PROJECT_reactNativeArchitectures = 'x86_64'"],
210
210
  "New-Item -ItemType Directory -Force -Path $directory | Out-Null",
211
- "& robocopy.exe $source $directory /MIR /XD node_modules .expo .git .gradle .cxx .kotlin build /XF bun.lock bun.lockb .absolutejs-preserve-subst.cjs /NFL /NDL /NJH /NJS /NP",
211
+ "& robocopy.exe $source $directory /MIR /XD node_modules .expo .git .gradle .cxx .kotlin build /XF bun.lock bun.lockb .absolutejs-preserve-subst.cjs .absolutejs-source-lock.sha256 /NFL /NDL /NJH /NJS /NP",
212
212
  "$copyExit = $LASTEXITCODE",
213
213
  "if ($copyExit -ge 8) { exit $copyExit }",
214
214
  "Set-Location $directory",
215
+ "$sourceLock = @('bun.lock', 'bun.lockb') | ForEach-Object { Join-Path $source $_ } | Where-Object { Test-Path $_ } | Select-Object -First 1",
216
+ "$sourceLockHash = if ($sourceLock) { (Get-FileHash $sourceLock -Algorithm SHA256).Hash } else { 'none' }",
217
+ "$lockMarker = Join-Path $directory '.absolutejs-source-lock.sha256'",
218
+ "$priorLockHash = if (Test-Path $lockMarker) { (Get-Content $lockMarker -Raw).Trim() } else { '' }",
219
+ "if ($priorLockHash -ne $sourceLockHash) { Remove-Item (Join-Path $directory 'bun.lock'), (Join-Path $directory 'bun.lockb') -Force -ErrorAction SilentlyContinue; Set-Content $lockMarker $sourceLockHash -NoNewline }",
215
220
  "$bun = (Get-Command bun.exe -ErrorAction Stop).Source",
216
221
  "& $bun install",
217
222
  "if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }",
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  syncAbsoluteExpoWebAssets,
4
4
  writeAbsoluteExpoProject
5
- } from "./index-wqhbxtyp.js";
5
+ } from "./index-0t1cxstr.js";
6
6
  import"./index-ar4gz15x.js";
7
7
  import"./index-mywsk201.js";
8
8
  export {
@@ -23,7 +23,7 @@ import {
23
23
  writeFile
24
24
  } from "fs/promises";
25
25
  import { createHash as createHash2 } from "crypto";
26
- import { basename, dirname as dirname2, join as join4, relative as relative2, resolve as resolve3, sep } from "path";
26
+ import { basename, dirname as dirname2, join as join5, relative as relative2, resolve as resolve3, sep } from "path";
27
27
 
28
28
  // src/mobile/syncSchema.ts
29
29
  import { readFileSync } from "fs";
@@ -1405,6 +1405,127 @@ var absoluteExpoNativeObservabilityPaths = (project) => [
1405
1405
  ...absoluteExpoNativeObservabilityFiles(project).keys()
1406
1406
  ];
1407
1407
 
1408
+ // src/mobile/expoActivityResultRecovery.ts
1409
+ import { join as join4 } from "path";
1410
+ var HEADER2 = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
1411
+ `;
1412
+ var XML_HEADER2 = `<!-- Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync. -->
1413
+ `;
1414
+ var moduleConfig2 = `${JSON.stringify({
1415
+ android: {
1416
+ modules: [
1417
+ "expo.modules.absoluteactivityresultrecovery.AbsoluteActivityResultRecoveryModule"
1418
+ ]
1419
+ },
1420
+ platforms: ["android"]
1421
+ }, null, 2)}
1422
+ `;
1423
+ var androidBuild2 = `${HEADER2}plugins {
1424
+ id 'com.android.library'
1425
+ id 'expo-module-gradle-plugin'
1426
+ }
1427
+
1428
+ group = 'expo.modules.absoluteactivityresultrecovery'
1429
+ version = '0.0.1'
1430
+
1431
+ android {
1432
+ namespace 'expo.modules.absoluteactivityresultrecovery'
1433
+ defaultConfig {
1434
+ versionCode 1
1435
+ versionName '0.0.1'
1436
+ }
1437
+ lintOptions { abortOnError false }
1438
+ }
1439
+ `;
1440
+ var androidManifest2 = `${XML_HEADER2}<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
1441
+ `;
1442
+ var androidModule2 = `${HEADER2}package expo.modules.absoluteactivityresultrecovery
1443
+
1444
+ import android.content.Intent
1445
+ import android.util.Log
1446
+ import expo.modules.kotlin.modules.Module
1447
+ import expo.modules.kotlin.modules.ModuleDefinition
1448
+
1449
+ data class AbsolutePendingActivityResult(
1450
+ val requestCode: Int,
1451
+ val resultCode: Int,
1452
+ val data: Intent?
1453
+ )
1454
+
1455
+ object AbsoluteActivityResultRecoveryState {
1456
+ @Volatile
1457
+ var applicationRuntimeReady = false
1458
+
1459
+ private val pendingActivityResults = ArrayDeque<AbsolutePendingActivityResult>()
1460
+
1461
+ @Synchronized
1462
+ fun enqueueActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
1463
+ if (pendingActivityResults.size == 8) pendingActivityResults.removeFirst()
1464
+ pendingActivityResults.addLast(
1465
+ AbsolutePendingActivityResult(requestCode, resultCode, data?.let(::Intent))
1466
+ )
1467
+ Log.d("AbsoluteJS", "Queued early Android activity result; pending=" + pendingActivityResults.size)
1468
+ }
1469
+
1470
+ @Synchronized
1471
+ fun hasPendingActivityResults() = pendingActivityResults.isNotEmpty()
1472
+
1473
+ @Synchronized
1474
+ fun drainActivityResults(): List<AbsolutePendingActivityResult> {
1475
+ val drained = pendingActivityResults.toList()
1476
+ pendingActivityResults.clear()
1477
+ Log.d("AbsoluteJS", "Replaying queued Android activity results; count=" + drained.size)
1478
+ return drained
1479
+ }
1480
+ }
1481
+
1482
+ class AbsoluteActivityResultRecoveryModule : Module() {
1483
+ override fun definition() = ModuleDefinition {
1484
+ Name("AbsoluteActivityResultRecovery")
1485
+
1486
+ Function("markApplicationRuntimeReady") {
1487
+ AbsoluteActivityResultRecoveryState.applicationRuntimeReady = true
1488
+ Log.d("AbsoluteJS", "Expo application runtime ready for Android activity results")
1489
+ }
1490
+ }
1491
+ }
1492
+ `;
1493
+ var runtime = `${HEADER2}import { requireNativeModule } from 'expo-modules-core';
1494
+
1495
+ type AbsoluteActivityResultRecoveryNative = {
1496
+ markApplicationRuntimeReady(): void;
1497
+ };
1498
+
1499
+ const native = requireNativeModule<AbsoluteActivityResultRecoveryNative>(
1500
+ 'AbsoluteActivityResultRecovery'
1501
+ );
1502
+
1503
+ export const markAbsoluteApplicationRuntimeReady = () =>
1504
+ native.markApplicationRuntimeReady();
1505
+ `;
1506
+ var absoluteExpoActivityResultRecoveryFiles = (project) => new Map([
1507
+ [
1508
+ join4(project, "modules/absolute-activity-result-recovery/expo-module.config.json"),
1509
+ moduleConfig2
1510
+ ],
1511
+ [
1512
+ join4(project, "modules/absolute-activity-result-recovery/android/build.gradle"),
1513
+ androidBuild2
1514
+ ],
1515
+ [
1516
+ join4(project, "modules/absolute-activity-result-recovery/android/src/main/AndroidManifest.xml"),
1517
+ androidManifest2
1518
+ ],
1519
+ [
1520
+ join4(project, "modules/absolute-activity-result-recovery/android/src/main/java/expo/modules/absoluteactivityresultrecovery/AbsoluteActivityResultRecoveryModule.kt"),
1521
+ androidModule2
1522
+ ],
1523
+ [
1524
+ join4(project, "src/generated/AbsoluteActivityResultRecovery.ts"),
1525
+ runtime
1526
+ ]
1527
+ ]);
1528
+
1408
1529
  // src/mobile/expoProject.ts
1409
1530
  var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
1410
1531
  `;
@@ -1485,7 +1606,7 @@ var routeSegments = (route) => {
1485
1606
  return segment;
1486
1607
  });
1487
1608
  };
1488
- var routeFile = (project, route) => join4(project, "app", ...routeSegments(route), "index.tsx");
1609
+ var routeFile = (project, route) => join5(project, "app", ...routeSegments(route), "index.tsx");
1489
1610
  var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map((spec) => {
1490
1611
  const separator = spec.lastIndexOf("@");
1491
1612
  return [spec.slice(0, separator), spec.slice(separator + 1)];
@@ -1493,7 +1614,7 @@ var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map
1493
1614
  var expoPackage = (auth, sync, devices, updates) => ({
1494
1615
  dependencies: {
1495
1616
  "@absolutejs/devices": "0.7.0",
1496
- "@absolutejs/devices-expo": "0.0.3",
1617
+ "@absolutejs/devices-expo": "0.0.9",
1497
1618
  ...auth ? {
1498
1619
  "@absolutejs/auth": ABSOLUTE_EXPO_AUTH_CORE_VERSION,
1499
1620
  [ABSOLUTE_EXPO_AUTH_PACKAGE]: ABSOLUTE_EXPO_AUTH_VERSION
@@ -1629,6 +1750,7 @@ var expoAppConfig = (config, auth, sync, devices, runtimeFingerprint) => {
1629
1750
  plugins: [
1630
1751
  "expo-router",
1631
1752
  ["expo-dev-client", { launchMode: "most-recent" }],
1753
+ "./plugins/withAbsoluteActivityResultRecovery",
1632
1754
  ...auth || config.updates ? ["expo-secure-store"] : [],
1633
1755
  ...sync ? [
1634
1756
  "expo-sqlite",
@@ -1718,6 +1840,77 @@ const withAbsoluteDevelopmentCa = config => {
1718
1840
 
1719
1841
  module.exports = withAbsoluteDevelopmentCa;
1720
1842
  `;
1843
+ var expoActivityResultRecoveryPlugin = `${EXPO_GENERATED_HEADER}const { withMainActivity } = require('expo/config-plugins');
1844
+
1845
+ const IMPORT_ANCHOR = 'import android.os.Bundle';
1846
+ const CLASS_ANCHOR = 'class MainActivity : ReactActivity() {';
1847
+ const RECOVERY_MARKER = 'absolutePendingActivityResults';
1848
+
1849
+ const withAbsoluteActivityResultRecovery = config => withMainActivity(config, value => {
1850
+ if (value.modResults.language !== 'kt') {
1851
+ throw new Error('AbsoluteJS Expo activity-result recovery requires a Kotlin MainActivity.');
1852
+ }
1853
+ let source = value.modResults.contents;
1854
+ if (source.includes(RECOVERY_MARKER)) return value;
1855
+ if (!source.includes(IMPORT_ANCHOR) || !source.includes(CLASS_ANCHOR)) {
1856
+ throw new Error('AbsoluteJS could not locate the Expo MainActivity integration points.');
1857
+ }
1858
+ source = source.replace(IMPORT_ANCHOR, [
1859
+ 'import android.content.Intent',
1860
+ 'import android.os.Bundle',
1861
+ 'import android.os.Handler',
1862
+ 'import android.os.Looper',
1863
+ 'import expo.modules.absoluteactivityresultrecovery.AbsoluteActivityResultRecoveryState'
1864
+ ].join('\\n'));
1865
+ source = source.replace(CLASS_ANCHOR, \`\${CLASS_ANCHOR}
1866
+ private val absoluteActivityResultHandler = Handler(Looper.getMainLooper())
1867
+ private var absoluteActivityResultAttempts = 0
1868
+ private val absoluteReplayActivityResults = object : Runnable {
1869
+ override fun run() {
1870
+ if (isFinishing || isDestroyed || !AbsoluteActivityResultRecoveryState.hasPendingActivityResults()) return
1871
+ if (!AbsoluteActivityResultRecoveryState.applicationRuntimeReady) {
1872
+ if (absoluteActivityResultAttempts++ < 240) {
1873
+ absoluteActivityResultHandler.postDelayed(this, 250)
1874
+ }
1875
+ return
1876
+ }
1877
+ absoluteActivityResultAttempts = 0
1878
+ AbsoluteActivityResultRecoveryState.drainActivityResults().forEach { result ->
1879
+ super@MainActivity.onActivityResult(result.requestCode, result.resultCode, result.data)
1880
+ }
1881
+ }
1882
+ }
1883
+
1884
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
1885
+ if (AbsoluteActivityResultRecoveryState.applicationRuntimeReady) {
1886
+ super.onActivityResult(requestCode, resultCode, data)
1887
+ return
1888
+ }
1889
+ AbsoluteActivityResultRecoveryState.enqueueActivityResult(requestCode, resultCode, data)
1890
+ absoluteActivityResultHandler.removeCallbacks(absoluteReplayActivityResults)
1891
+ absoluteActivityResultHandler.postDelayed(absoluteReplayActivityResults, 250)
1892
+ }
1893
+
1894
+ override fun onResume() {
1895
+ super.onResume()
1896
+ if (AbsoluteActivityResultRecoveryState.hasPendingActivityResults()) {
1897
+ absoluteActivityResultAttempts = 0
1898
+ absoluteActivityResultHandler.removeCallbacks(absoluteReplayActivityResults)
1899
+ absoluteActivityResultHandler.post(absoluteReplayActivityResults)
1900
+ }
1901
+ }
1902
+
1903
+ override fun onDestroy() {
1904
+ absoluteActivityResultHandler.removeCallbacks(absoluteReplayActivityResults)
1905
+ super.onDestroy()
1906
+ }
1907
+ \`);
1908
+ value.modResults.contents = source;
1909
+ return value;
1910
+ });
1911
+
1912
+ module.exports = withAbsoluteActivityResultRecovery;
1913
+ `;
1721
1914
  var metroConfig = (projectRoot) => `${EXPO_GENERATED_HEADER}const { getDefaultConfig } = require('expo/metro-config');
1722
1915
  const path = require('node:path');
1723
1916
 
@@ -1735,6 +1928,8 @@ module.exports = config;
1735
1928
  `;
1736
1929
  var layoutSource = (auth, sync, updates, observability) => `${EXPO_GENERATED_HEADER}import { Stack } from 'expo-router';
1737
1930
  import '../src/generated/AbsoluteDevices';
1931
+ import { useEffect as useActivityResultRecoveryEffect } from 'react';
1932
+ import { markAbsoluteApplicationRuntimeReady } from '../src/generated/AbsoluteActivityResultRecovery';
1738
1933
  ${auth ? `import { useEffect, useState } from 'react';
1739
1934
  import { startAbsoluteExpoAuth } from '../src/generated/AbsoluteAuth';` : ""}
1740
1935
  ${sync ? "import { startAbsoluteExpoSync } from '../src/generated/AbsoluteSync';" : ""}
@@ -1744,6 +1939,9 @@ ${observability ? `import { useEffect as useNativeObservabilityEffect } from 're
1744
1939
  import { startAbsoluteExpoNativeObservability } from '../src/generated/AbsoluteNativeObservability';` : ""}
1745
1940
 
1746
1941
  export default function AbsoluteLayout() {
1942
+ useActivityResultRecoveryEffect(() => {
1943
+ markAbsoluteApplicationRuntimeReady();
1944
+ }, []);
1747
1945
  ${updates ? "useUpdateEffect(() => { void startAbsoluteExpoUpdates(); }, []);" : ""}
1748
1946
  ${observability ? "useNativeObservabilityEffect(() => { void startAbsoluteExpoNativeObservability(); }, []);" : ""}
1749
1947
  ${auth ? `const [ready, setReady] = useState(false);
@@ -2608,8 +2806,8 @@ const styles = StyleSheet.create({
2608
2806
  error: { color: '#b91c1c', fontSize: 16, textAlign: 'center' }
2609
2807
  });
2610
2808
  `;
2611
- var nativeWrapperSource = (wrapper, module, runtime, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative(dirname2(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
2612
- import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative(dirname2(wrapper), runtime).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
2809
+ var nativeWrapperSource = (wrapper, module, runtime2, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative(dirname2(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
2810
+ import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative(dirname2(wrapper), runtime2).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
2613
2811
 
2614
2812
  export const ErrorBoundary = createAbsoluteNativeRouteErrorBoundary(${JSON.stringify(route)});
2615
2813
  export default createAbsoluteNativeRoute(ApplicationNativeRoute, ${JSON.stringify(route)});
@@ -2678,7 +2876,7 @@ var pruneManagedFiles = async (paths) => {
2678
2876
  return removed.filter(Boolean).length;
2679
2877
  };
2680
2878
  var pruneStaleManagedExpoRoutes = async (project, expected) => {
2681
- const appDirectory = join4(project, "app");
2879
+ const appDirectory = join5(project, "app");
2682
2880
  if (!await exists(appDirectory))
2683
2881
  return 0;
2684
2882
  const files = await walkFiles(appDirectory);
@@ -2726,7 +2924,7 @@ var writeAbsoluteExpoProject = async (config, options) => {
2726
2924
  if (missing) {
2727
2925
  throw new TypeError(`Expo native route ${missing.route} references missing module ${missing.module}.`);
2728
2926
  }
2729
- const marker = join4(project, EXPO_PROJECT_MARKER);
2927
+ const marker = join5(project, EXPO_PROJECT_MARKER);
2730
2928
  if (await exists(project) && !await exists(marker)) {
2731
2929
  const entries = await readdir(project);
2732
2930
  if (entries.length > 0 && !options.force) {
@@ -2739,7 +2937,7 @@ var writeAbsoluteExpoProject = async (config, options) => {
2739
2937
  const authEnabled = Boolean(auth);
2740
2938
  const files = new Map([
2741
2939
  [
2742
- join4(project, ".gitignore"),
2940
+ join5(project, ".gitignore"),
2743
2941
  `.expo/
2744
2942
  android/
2745
2943
  ios/
@@ -2747,74 +2945,80 @@ node_modules/
2747
2945
  `
2748
2946
  ],
2749
2947
  [
2750
- join4(project, "app.json"),
2948
+ join5(project, "app.json"),
2751
2949
  jsonSource(expoAppConfig(config, authEnabled, syncEnabled, devices, runtimeFingerprint))
2752
2950
  ],
2753
- [join4(project, "app.config.js"), expoDynamicAppConfig],
2951
+ [join5(project, "app.config.js"), expoDynamicAppConfig],
2754
2952
  [
2755
- join4(project, "package.json"),
2953
+ join5(project, "package.json"),
2756
2954
  jsonSource(expoPackage(authEnabled, syncEnabled, devices, config.updates !== undefined))
2757
2955
  ],
2758
- [join4(project, "metro.config.js"), metroConfig(projectRoot)],
2956
+ [join5(project, "metro.config.js"), metroConfig(projectRoot)],
2759
2957
  [
2760
- join4(project, "plugins", "withAbsoluteDevelopmentCa.js"),
2958
+ join5(project, "plugins", "withAbsoluteDevelopmentCa.js"),
2761
2959
  expoDevelopmentCaPlugin
2762
2960
  ],
2763
2961
  [
2764
- join4(project, "tsconfig.json"),
2962
+ join5(project, "plugins", "withAbsoluteActivityResultRecovery.js"),
2963
+ expoActivityResultRecoveryPlugin
2964
+ ],
2965
+ [
2966
+ join5(project, "tsconfig.json"),
2765
2967
  jsonSource(expoTsConfig(projectRoot, project, authEnabled, syncEnabled))
2766
2968
  ],
2767
2969
  [
2768
- join4(project, "app", "_layout.tsx"),
2970
+ join5(project, "app", "_layout.tsx"),
2769
2971
  layoutSource(authEnabled, syncEnabled, config.updates !== undefined, config.observability !== undefined)
2770
2972
  ],
2771
2973
  [
2772
- join4(project, "app", "__absolute", "native", "index.tsx"),
2974
+ join5(project, "app", "__absolute", "native", "index.tsx"),
2773
2975
  nativeDiagnosticSource
2774
2976
  ],
2775
2977
  [
2776
- join4(project, "src", "generated", "AbsoluteDevices.ts"),
2978
+ join5(project, "src", "generated", "AbsoluteDevices.ts"),
2777
2979
  devicesRuntimeSource(config, devices, authEnabled)
2778
2980
  ],
2779
2981
  [
2780
- join4(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
2982
+ join5(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
2781
2983
  nativeRouteRuntimeSource(authEnabled)
2782
2984
  ],
2783
2985
  [
2784
- join4(project, "src", "generated", "AbsoluteWebHost.tsx"),
2986
+ join5(project, "src", "generated", "AbsoluteWebHost.tsx"),
2785
2987
  webHostSource(config, auth, syncEnabled)
2786
2988
  ]
2787
2989
  ]);
2990
+ for (const [path, source] of absoluteExpoActivityResultRecoveryFiles(project))
2991
+ files.set(path, source);
2788
2992
  if (config.observability) {
2789
2993
  for (const [path, source] of absoluteExpoNativeObservabilityFiles(project))
2790
2994
  files.set(path, source);
2791
2995
  }
2792
2996
  if (config.updates) {
2793
- files.set(join4(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
2997
+ files.set(join5(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
2794
2998
  }
2795
2999
  const expoCodeSigning = config.updates?.expoCodeSigning;
2796
3000
  if (expoCodeSigning)
2797
- files.set(join4(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
3001
+ files.set(join5(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
2798
3002
  if (auth) {
2799
- files.set(join4(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
3003
+ files.set(join5(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
2800
3004
  }
2801
3005
  if (syncSchema) {
2802
- files.set(join4(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
3006
+ files.set(join5(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
2803
3007
  }
2804
- const webAssetsPath = join4(project, "src", "generated", "webAssets.ts");
3008
+ const webAssetsPath = join5(project, "src", "generated", "webAssets.ts");
2805
3009
  if (!await exists(webAssetsPath)) {
2806
3010
  files.set(webAssetsPath, emptyWebAssetsSource);
2807
3011
  }
2808
3012
  if (!config.expoNativeRoutes["/"]) {
2809
- files.set(join4(project, "app", "index.tsx"), webRouteSource);
3013
+ files.set(join5(project, "app", "index.tsx"), webRouteSource);
2810
3014
  }
2811
- files.set(join4(project, "app", "[...absolute].tsx"), catchAllRouteSource);
2812
- const nativeRouteRuntime = join4(project, "src", "generated", "AbsoluteNativeRoute.tsx");
3015
+ files.set(join5(project, "app", "[...absolute].tsx"), catchAllRouteSource);
3016
+ const nativeRouteRuntime = join5(project, "src", "generated", "AbsoluteNativeRoute.tsx");
2813
3017
  for (const [route, module] of routeModules) {
2814
- const wrapper = route === "/" ? join4(project, "app", "index.tsx") : routeFile(project, route);
3018
+ const wrapper = route === "/" ? join5(project, "app", "index.tsx") : routeFile(project, route);
2815
3019
  files.set(wrapper, nativeWrapperSource(wrapper, module, nativeRouteRuntime, route));
2816
3020
  }
2817
- const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join4(project, "app")}${sep}`))));
3021
+ const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join5(project, "app")}${sep}`))));
2818
3022
  const removedObservability = config.observability ? 0 : await pruneManagedFiles(absoluteExpoNativeObservabilityPaths(project));
2819
3023
  const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
2820
3024
  const changed = removedRoutes + removedObservability + changes.filter(Boolean).length;
@@ -2823,7 +3027,7 @@ node_modules/
2823
3027
  var walkFiles = async (root, directory = root) => {
2824
3028
  const entries = await readdir(directory, { withFileTypes: true });
2825
3029
  const nested = await Promise.all(entries.map((entry) => {
2826
- const path = join4(directory, entry.name);
3030
+ const path = join5(directory, entry.name);
2827
3031
  if (entry.isDirectory())
2828
3032
  return walkFiles(root, path);
2829
3033
  if (entry.isFile())
@@ -2890,11 +3094,11 @@ export const materializeAbsoluteWebBundle = async () => {
2890
3094
  var syncAbsoluteExpoWebAssets = async (config) => {
2891
3095
  if (config.engine !== "expo")
2892
3096
  throw new TypeError("Expo asset sync requires mobile.engine: expo.");
2893
- const marker = join4(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
3097
+ const marker = join5(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
2894
3098
  if (!await exists(marker)) {
2895
3099
  throw new TypeError("Expo asset sync requires an AbsoluteJS-managed Expo project. Run mobile init first.");
2896
3100
  }
2897
- const manifestPath = join4(config.bundleDirectory, "absolute-mobile-manifest.json");
3101
+ const manifestPath = join5(config.bundleDirectory, "absolute-mobile-manifest.json");
2898
3102
  const manifest = JSON.parse(await readFile(manifestPath, "utf8"));
2899
3103
  const nativeDataManifest = expoNativeDataManifest(manifest);
2900
3104
  const { appBuild } = nativeDataManifest;
@@ -2908,16 +3112,16 @@ var syncAbsoluteExpoWebAssets = async (config) => {
2908
3112
  bundleHash.update("\x00");
2909
3113
  });
2910
3114
  const bundleId = `amexpo_${bundleHash.digest("hex")}`;
2911
- const destination = join4(config.nativeProjectDirectory, "assets", "absolute");
3115
+ const destination = join5(config.nativeProjectDirectory, "assets", "absolute");
2912
3116
  await mkdir(dirname2(destination), { recursive: true });
2913
- const staging = await mkdtemp(join4(dirname2(destination), `.${basename(destination)}.stage-`));
3117
+ const staging = await mkdtemp(join5(dirname2(destination), `.${basename(destination)}.stage-`));
2914
3118
  let assets;
2915
3119
  try {
2916
3120
  assets = await Promise.all(files.map(async (source, index) => {
2917
3121
  const name = `${String(index).padStart(6, "0")}${EXPO_ASSET_EXTENSION}`;
2918
- await cp(source, join4(staging, name));
3122
+ await cp(source, join5(staging, name));
2919
3123
  return {
2920
- asset: portableRelative(join4(config.nativeProjectDirectory, "src", "generated"), join4(destination, name)),
3124
+ asset: portableRelative(join5(config.nativeProjectDirectory, "src", "generated"), join5(destination, name)),
2921
3125
  path: relative2(config.bundleDirectory, source).replaceAll("\\", "/")
2922
3126
  };
2923
3127
  }));
@@ -2926,7 +3130,7 @@ var syncAbsoluteExpoWebAssets = async (config) => {
2926
3130
  await rm(staging, { force: true, recursive: true });
2927
3131
  throw error;
2928
3132
  }
2929
- const generated = join4(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
3133
+ const generated = join5(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
2930
3134
  await writeManagedFile(generated, assetModuleSource(assets, bundleId, nativeDataManifest), true);
2931
3135
  return { appBuild, assets: assets.length, bundleId, path: destination };
2932
3136
  };
@@ -6,7 +6,7 @@ import {
6
6
  createIslandRegistryDefinitionPlugin,
7
7
  finalizeAbsoluteMobileCompatibilityBuild,
8
8
  resolveServerBundleExternals
9
- } from "./index-kh44yx23.js";
9
+ } from "./index-d8va9b7v.js";
10
10
  import {
11
11
  loadIslandRegistryBuildInfo
12
12
  } from "./index-bzs19w3r.js";
@@ -10,7 +10,7 @@ import {
10
10
  resolveAbsoluteMobileUpdateRuntime,
11
11
  syncAbsoluteExpoWebAssets,
12
12
  writeAbsoluteExpoProject
13
- } from "./index-wqhbxtyp.js";
13
+ } from "./index-0t1cxstr.js";
14
14
 
15
15
  // src/build/islandRegistryTransform.ts
16
16
  import { basename } from "path";
package/dist/cli/index.js CHANGED
@@ -58,7 +58,7 @@ if (command === "dev") {
58
58
  }
59
59
  const positionalArgs = stripNamedArgs("--config", "--android-device", "--ios-device").filter((arg) => arg !== "--no-mobile" && arg !== "--eager");
60
60
  const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
61
- const { dev } = await import("./dev-01zcxngn.js");
61
+ const { dev } = await import("./dev-sm9px53g.js");
62
62
  await dev(serverEntry, configPath, {
63
63
  androidDevice,
64
64
  eager: args.includes("--eager"),
@@ -71,7 +71,7 @@ if (command === "dev") {
71
71
  const configPath = parseNamedArg("--config");
72
72
  const positionalArgs = stripNamedArgs("--outdir", "--config").filter((arg) => arg !== "--prebuilt");
73
73
  const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
74
- const { start } = await import("./start-dw5crgp7.js");
74
+ const { start } = await import("./start-0ddnh0y4.js");
75
75
  await start(serverEntry, outdir, configPath, {
76
76
  prebuilt: args.includes("--prebuilt")
77
77
  });
@@ -81,7 +81,7 @@ if (command === "dev") {
81
81
  const configPath = parseNamedArg("--config");
82
82
  const positionalArgs = stripNamedArgs("--outdir", "--config");
83
83
  const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
84
- const { start } = await import("./start-dw5crgp7.js");
84
+ const { start } = await import("./start-0ddnh0y4.js");
85
85
  await start(serverEntry, outdir, configPath, { prepareOnly: true });
86
86
  } else if (command === "build") {
87
87
  sendTelemetryEvent("cli:command", { command });
@@ -197,13 +197,13 @@ if (command === "dev") {
197
197
  const configPath = parseNamedArg("--config");
198
198
  const positionalArgs = stripNamedArgs("--outdir", "--outfile", "--config");
199
199
  const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
200
- const { compile } = await import("./compile-wkfd88w7.js");
200
+ const { compile } = await import("./compile-qg75ewma.js");
201
201
  await compile(serverEntry, outdir, outfile, configPath);
202
202
  } else if (command === "mobile") {
203
203
  sendTelemetryEvent("cli:command", {
204
204
  command: `mobile:${workspaceCommand ?? "unknown"}`
205
205
  });
206
- const { runMobile } = await import("./mobile-pbe1a667.js");
206
+ const { runMobile } = await import("./mobile-dev4mjsa.js");
207
207
  try {
208
208
  await runMobile(args);
209
209
  } catch (error) {