@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 +12 -0
- package/changelog.json +20 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/{compile-wkfd88w7.js → compile-qg75ewma.js} +2 -2
- package/dist/cli/{dev-01zcxngn.js → dev-sm9px53g.js} +2 -2
- package/dist/cli/{expoDevController-k15hftqn.js → expoDevController-a0jk8d43.js} +6 -1
- package/dist/cli/{expoProject-mmm3s62b.js → expoProject-h38entbj.js} +1 -1
- package/dist/cli/{index-wqhbxtyp.js → index-0t1cxstr.js} +241 -37
- package/dist/cli/{index-v5knwk7v.js → index-51yyq29s.js} +1 -1
- package/dist/cli/{index-kh44yx23.js → index-d8va9b7v.js} +1 -1
- package/dist/cli/index.js +5 -5
- package/dist/cli/{mobile-pbe1a667.js → mobile-dev4mjsa.js} +3 -3
- package/dist/cli/{start-dw5crgp7.js → start-0ddnh0y4.js} +3 -3
- package/dist/mobile/index.js +309 -99
- package/dist/mobile/index.js.map +7 -6
- package/dist/mobile/remoteMacAgentEntry.js +331 -174
- package/dist/src/mobile/expoActivityResultRecovery.d.ts +1 -0
- package/dist/src/mobile/expoBridge.d.ts +2 -2
- package/package.json +3 -2
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
1290
|
-
import("./expoDevController-
|
|
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 }",
|
|
@@ -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
|
|
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) =>
|
|
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.
|
|
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,
|
|
2612
|
-
import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative(dirname2(wrapper),
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
2948
|
+
join5(project, "app.json"),
|
|
2751
2949
|
jsonSource(expoAppConfig(config, authEnabled, syncEnabled, devices, runtimeFingerprint))
|
|
2752
2950
|
],
|
|
2753
|
-
[
|
|
2951
|
+
[join5(project, "app.config.js"), expoDynamicAppConfig],
|
|
2754
2952
|
[
|
|
2755
|
-
|
|
2953
|
+
join5(project, "package.json"),
|
|
2756
2954
|
jsonSource(expoPackage(authEnabled, syncEnabled, devices, config.updates !== undefined))
|
|
2757
2955
|
],
|
|
2758
|
-
[
|
|
2956
|
+
[join5(project, "metro.config.js"), metroConfig(projectRoot)],
|
|
2759
2957
|
[
|
|
2760
|
-
|
|
2958
|
+
join5(project, "plugins", "withAbsoluteDevelopmentCa.js"),
|
|
2761
2959
|
expoDevelopmentCaPlugin
|
|
2762
2960
|
],
|
|
2763
2961
|
[
|
|
2764
|
-
|
|
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
|
-
|
|
2970
|
+
join5(project, "app", "_layout.tsx"),
|
|
2769
2971
|
layoutSource(authEnabled, syncEnabled, config.updates !== undefined, config.observability !== undefined)
|
|
2770
2972
|
],
|
|
2771
2973
|
[
|
|
2772
|
-
|
|
2974
|
+
join5(project, "app", "__absolute", "native", "index.tsx"),
|
|
2773
2975
|
nativeDiagnosticSource
|
|
2774
2976
|
],
|
|
2775
2977
|
[
|
|
2776
|
-
|
|
2978
|
+
join5(project, "src", "generated", "AbsoluteDevices.ts"),
|
|
2777
2979
|
devicesRuntimeSource(config, devices, authEnabled)
|
|
2778
2980
|
],
|
|
2779
2981
|
[
|
|
2780
|
-
|
|
2982
|
+
join5(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
|
|
2781
2983
|
nativeRouteRuntimeSource(authEnabled)
|
|
2782
2984
|
],
|
|
2783
2985
|
[
|
|
2784
|
-
|
|
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(
|
|
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(
|
|
3001
|
+
files.set(join5(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
|
|
2798
3002
|
if (auth) {
|
|
2799
|
-
files.set(
|
|
3003
|
+
files.set(join5(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
|
|
2800
3004
|
}
|
|
2801
3005
|
if (syncSchema) {
|
|
2802
|
-
files.set(
|
|
3006
|
+
files.set(join5(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
|
|
2803
3007
|
}
|
|
2804
|
-
const webAssetsPath =
|
|
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(
|
|
3013
|
+
files.set(join5(project, "app", "index.tsx"), webRouteSource);
|
|
2810
3014
|
}
|
|
2811
|
-
files.set(
|
|
2812
|
-
const nativeRouteRuntime =
|
|
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 === "/" ?
|
|
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(`${
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
3115
|
+
const destination = join5(config.nativeProjectDirectory, "assets", "absolute");
|
|
2912
3116
|
await mkdir(dirname2(destination), { recursive: true });
|
|
2913
|
-
const staging = await mkdtemp(
|
|
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,
|
|
3122
|
+
await cp(source, join5(staging, name));
|
|
2919
3123
|
return {
|
|
2920
|
-
asset: portableRelative(
|
|
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 =
|
|
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
|
};
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
206
|
+
const { runMobile } = await import("./mobile-dev4mjsa.js");
|
|
207
207
|
try {
|
|
208
208
|
await runMobile(args);
|
|
209
209
|
} catch (error) {
|