@absolutejs/absolute 0.20.0-beta.92 → 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.
Files changed (39) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/changelog.json +48 -0
  3. package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
  4. package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
  5. package/dist/build/buildWorker.js +10 -1
  6. package/dist/build.js +16 -7
  7. package/dist/build.js.map +9 -8
  8. package/dist/cli/{compile-vf61bv90.js → compile-qg75ewma.js} +5 -5
  9. package/dist/cli/{dev-perzmh2w.js → dev-sm9px53g.js} +83 -11
  10. package/dist/cli/{expoDevController-tr63cg78.js → expoDevController-a0jk8d43.js} +31 -2
  11. package/dist/cli/expoNativeWatcher-rmc95bak.js +138 -0
  12. package/dist/cli/{expoProject-djc0vk7g.js → expoProject-h38entbj.js} +1 -1
  13. package/dist/cli/{index-8zrnvazp.js → index-0t1cxstr.js} +261 -48
  14. package/dist/cli/{index-fn44wefq.js → index-3sdvzrv2.js} +37 -28
  15. package/dist/cli/{index-gxkmg2ss.js → index-51yyq29s.js} +1 -1
  16. package/dist/cli/index-bw4ktfnz.js +11 -0
  17. package/dist/cli/{index-751czk1b.js → index-d8va9b7v.js} +1 -1
  18. package/dist/cli/index.js +5 -5
  19. package/dist/cli/{mobile-yk7qr9qg.js → mobile-dev4mjsa.js} +20 -12
  20. package/dist/cli/{remoteMacProtocol-vw931n0a.js → remoteMacProtocol-kqvkp0qd.js} +2 -1
  21. package/dist/cli/{start-ef7tgbmf.js → start-0ddnh0y4.js} +3 -3
  22. package/dist/dev/client/handlers/svelte.ts +11 -15
  23. package/dist/dev/serverBootstrap.js +10 -1
  24. package/dist/index.js +17 -8
  25. package/dist/index.js.map +11 -10
  26. package/dist/mobile/index.js +599 -208
  27. package/dist/mobile/index.js.map +11 -8
  28. package/dist/mobile/mobilePreviewClient.ts +1 -1
  29. package/dist/mobile/remoteMacAgentEntry.js +354 -188
  30. package/dist/src/dev/clientManager.d.ts +2 -2
  31. package/dist/src/mobile/androidConformance.d.ts +4 -1
  32. package/dist/src/mobile/expoActivityResultRecovery.d.ts +1 -0
  33. package/dist/src/mobile/expoBridge.d.ts +2 -2
  34. package/dist/src/mobile/expoDevController.d.ts +2 -6
  35. package/dist/src/mobile/expoNativeWatcher.d.ts +21 -0
  36. package/dist/src/mobile/index.d.ts +1 -0
  37. package/dist/src/mobile/remoteMacProtocol.d.ts +1 -4
  38. package/dist/src/utils/unrefTimer.d.ts +5 -0
  39. package/package.json +5 -2
@@ -596,6 +596,15 @@ var init_startupBanner = __esm(() => {
596
596
  ];
597
597
  });
598
598
 
599
+ // src/utils/unrefTimer.ts
600
+ var unrefTimer = (timer) => {
601
+ if (timer === null || typeof timer !== "object" && typeof timer !== "function")
602
+ return;
603
+ const unref = Reflect.get(timer, "unref");
604
+ if (typeof unref === "function")
605
+ Reflect.apply(unref, timer, []);
606
+ };
607
+
599
608
  // src/mobile/config.ts
600
609
  var exports_config = {};
601
610
  __export(exports_config, {
@@ -19342,7 +19351,7 @@ var init_compatibilityDispatcher = __esm(() => {
19342
19351
  // src/cli/scripts/telemetry.ts
19343
19352
  import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync6, writeFileSync } from "fs";
19344
19353
  import { homedir as homedir3 } from "os";
19345
- import { join as join19 } from "path";
19354
+ import { join as join21 } from "path";
19346
19355
  var configDir, configPath, getTelemetryConfig = () => {
19347
19356
  try {
19348
19357
  if (!existsSync5(configPath))
@@ -19355,14 +19364,14 @@ var configDir, configPath, getTelemetryConfig = () => {
19355
19364
  }
19356
19365
  };
19357
19366
  var init_telemetry = __esm(() => {
19358
- configDir = join19(homedir3(), ".absolutejs");
19359
- configPath = join19(configDir, "telemetry.json");
19367
+ configDir = join21(homedir3(), ".absolutejs");
19368
+ configPath = join21(configDir, "telemetry.json");
19360
19369
  });
19361
19370
 
19362
19371
  // src/cli/telemetryEvent.ts
19363
19372
  import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
19364
19373
  import { arch, platform as platform3 } from "os";
19365
- import { dirname as dirname14, join as join20, parse } from "path";
19374
+ import { dirname as dirname14, join as join22, parse } from "path";
19366
19375
  var checkCandidate = (candidate) => {
19367
19376
  if (!existsSync6(candidate)) {
19368
19377
  return null;
@@ -19382,7 +19391,7 @@ var checkCandidate = (candidate) => {
19382
19391
  }, findPackageVersion = () => {
19383
19392
  let { dir } = import.meta;
19384
19393
  while (dir !== parse(dir).root) {
19385
- const candidate = join20(dir, "package.json");
19394
+ const candidate = join22(dir, "package.json");
19386
19395
  const version = checkCandidate(candidate);
19387
19396
  if (version) {
19388
19397
  return version;
@@ -20023,7 +20032,7 @@ __export(exports_mobileUpdate, {
20023
20032
  parseMobileUpdateManifest: () => parseMobileUpdateManifest
20024
20033
  });
20025
20034
  import {
20026
- createHash as createHash15,
20035
+ createHash as createHash16,
20027
20036
  createHmac,
20028
20037
  createPrivateKey,
20029
20038
  createPublicKey as createPublicKey2,
@@ -20033,7 +20042,7 @@ import {
20033
20042
  verify as verify2,
20034
20043
  X509Certificate as X509Certificate3
20035
20044
  } from "crypto";
20036
- import { readFile as readFile23, stat as stat5 } from "fs/promises";
20045
+ import { readFile as readFile24, stat as stat5 } from "fs/promises";
20037
20046
  import path from "path";
20038
20047
  var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updates", MAX_FILE_BYTES, MAX_TOTAL_BYTES, DAY_MS, DEFAULT_MIN_AGE_MS, DEFAULT_GRACE_PERIOD_MS, DEFAULT_RETAIN_RECENT = 5, HASH, RELEASE, APP_ID, NAME, EXPO_DESCRIPTOR = "_absolute/expo-update.json", EXPO_CODE_SIGNING_ALGORITHM = "rsa-v1_5-sha256", HEALTH_TOKEN_VERSION = 1, HEALTH_KINDS, FAILURE_HEALTH_KINDS, MobileUpdateRegistryError, object6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), text2 = (value, field2) => {
20039
20048
  if (typeof value !== "string" || value.length === 0)
@@ -20183,7 +20192,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20183
20192
  if (!prefix || prefix.split("/").some((segment) => segment === "." || segment === ".."))
20184
20193
  throw new MobileUpdateRegistryError("Mobile update prefix is invalid");
20185
20194
  return prefix;
20186
- }, appHash = (appId) => createHash15("sha256").update(appId).digest("hex"), digest = (bytes) => createHash15("sha256").update(bytes).digest("hex"), json = (value) => new TextEncoder().encode(`${JSON.stringify(value, null, 2)}
20195
+ }, appHash = (appId) => createHash16("sha256").update(appId).digest("hex"), digest = (bytes) => createHash16("sha256").update(bytes).digest("hex"), json = (value) => new TextEncoder().encode(`${JSON.stringify(value, null, 2)}
20187
20196
  `), decode2 = (value) => JSON.parse(new TextDecoder().decode(value)), fileDigest = async (file) => {
20188
20197
  const hasher = new Bun.CryptoHasher("sha256");
20189
20198
  for await (const chunk of file.stream())
@@ -20194,7 +20203,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20194
20203
  return false;
20195
20204
  if (input.rollout === 1)
20196
20205
  return true;
20197
- const value = createHash15("sha256").update(`${input.appId}\x00${input.channel}\x00${input.releaseId}\x00${input.installationId}`).digest().readUInt32BE(0);
20206
+ const value = createHash16("sha256").update(`${input.appId}\x00${input.channel}\x00${input.releaseId}\x00${input.installationId}`).digest().readUInt32BE(0);
20198
20207
  return value / 4294967296 < input.rollout;
20199
20208
  }, base64Url = (value) => Buffer.from(value).toString("base64url"), healthPromotionId = (channel) => channel.promotionId ?? digest(new TextEncoder().encode(`${channel.appId}\x00${channel.channel}\x00${channel.releaseId ?? "embedded"}\x00${channel.promotedAt}`)), finiteMetric = (value, field2) => {
20200
20209
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0)
@@ -21066,7 +21075,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21066
21075
  verifyManifestSignature(manifest, options.publicKeys);
21067
21076
  await assertNotMarked(manifest.appId, manifest.releaseId);
21068
21077
  const localRoot = path.resolve(input.releaseDirectory);
21069
- const localManifest = parseMobileUpdateManifest(JSON.parse(await readFile23(path.join(localRoot, "update.json"), "utf8")));
21078
+ const localManifest = parseMobileUpdateManifest(JSON.parse(await readFile24(path.join(localRoot, "update.json"), "utf8")));
21070
21079
  if (JSON.stringify(localManifest) !== JSON.stringify(manifest))
21071
21080
  throw new MobileUpdateRegistryError("Local mobile update manifest changed");
21072
21081
  const existing = await readManifest(manifest.appId, manifest.releaseId);
@@ -21199,7 +21208,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21199
21208
  }
21200
21209
  };
21201
21210
  }, expoUpdateId = (releaseId) => {
21202
- const hash = RELEASE.test(releaseId) ? releaseId.slice("amu_".length, "amu_".length + 32) : createHash15("sha256").update(releaseId).digest("hex").slice(0, 32);
21211
+ const hash = RELEASE.test(releaseId) ? releaseId.slice("amu_".length, "amu_".length + 32) : createHash16("sha256").update(releaseId).digest("hex").slice(0, 32);
21203
21212
  return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-${hash.slice(12, 16)}-${hash.slice(16, 20)}-${hash.slice(20)}`;
21204
21213
  }, expoContentType = (extension2, launch) => {
21205
21214
  if (launch)
@@ -21352,8 +21361,8 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21352
21361
  });
21353
21362
  }
21354
21363
  const pathname = new URL(request.url).pathname.replace(/^\/+/, "");
21355
- const relative17 = pathname.startsWith(`${route}/`) ? pathname.slice(route.length + 1) : "";
21356
- if (request.method === "POST" && relative17 === "health") {
21364
+ const relative18 = pathname.startsWith(`${route}/`) ? pathname.slice(route.length + 1) : "";
21365
+ if (request.method === "POST" && relative18 === "health") {
21357
21366
  if (!options.registry.recordUpdateHealth)
21358
21367
  return new Response(null, { status: 404 });
21359
21368
  const appId = request.headers.get("x-absolute-mobile-app");
@@ -21396,7 +21405,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21396
21405
  }
21397
21406
  if (request.method !== "GET")
21398
21407
  return new Response(null, { status: 405 });
21399
- if (relative17 === "update.json") {
21408
+ if (relative18 === "update.json") {
21400
21409
  const expoProtocolVersion = request.headers.get("expo-protocol-version");
21401
21410
  const expoProtocol = expoProtocolVersion !== null;
21402
21411
  if (expoProtocol && expoProtocolVersion !== "1")
@@ -21514,7 +21523,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21514
21523
  }
21515
21524
  });
21516
21525
  }
21517
- const match = /^(amu_[a-f0-9]{64})\/files\/(.+)$/.exec(relative17);
21526
+ const match = /^(amu_[a-f0-9]{64})\/files\/(.+)$/.exec(relative18);
21518
21527
  if (!match?.[1] || !match[2])
21519
21528
  return new Response(null, { status: 404 });
21520
21529
  const file = await options.registry.readUpdateFile({
@@ -21607,14 +21616,14 @@ import {
21607
21616
  createPublicKey as createPublicKey3,
21608
21617
  X509Certificate as X509Certificate4
21609
21618
  } from "crypto";
21610
- import { access as access16, mkdir as mkdir18 } from "fs/promises";
21611
- import { dirname as dirname19, isAbsolute as isAbsolute9, relative as relative17, resolve as resolve20, sep as sep11 } from "path";
21619
+ import { access as access17, mkdir as mkdir18 } from "fs/promises";
21620
+ import { dirname as dirname19, isAbsolute as isAbsolute9, relative as relative18, resolve as resolve20, sep as sep11 } from "path";
21612
21621
  import { pathToFileURL as pathToFileURL5 } from "url";
21613
21622
  import { Elysia as Elysia4 } from "elysia";
21614
21623
  var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE = "mobile.update.ts", object7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), projectPath3 = (projectRoot, requested) => {
21615
21624
  const root = resolve20(projectRoot);
21616
21625
  const path2 = resolve20(root, requested);
21617
- const projectRelative = relative17(root, path2);
21626
+ const projectRelative = relative18(root, path2);
21618
21627
  if (projectRelative === ".." || projectRelative.startsWith(`..${sep11}`) || isAbsolute9(projectRelative))
21619
21628
  throw new TypeError("mobile.updates.server.registry must remain inside the project.");
21620
21629
  return path2;
@@ -21638,7 +21647,7 @@ var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MOD
21638
21647
  return metadata;
21639
21648
  }, loadAbsoluteMobileUpdateServerModule = async (projectRoot, requestedModulePath = DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE) => {
21640
21649
  const modulePath = projectPath3(projectRoot, requestedModulePath);
21641
- await access16(modulePath).catch(() => {
21650
+ await access17(modulePath).catch(() => {
21642
21651
  throw new TypeError(`Mobile update server registry does not exist: ${modulePath}. Run \`absolute mobile update provision\`.`);
21643
21652
  });
21644
21653
  const loaded = await import(pathToFileURL5(modulePath).href);
@@ -21827,7 +21836,7 @@ ${generated}`);
21827
21836
  }, writeAbsoluteMobileUpdateRegistry = async (options) => {
21828
21837
  const path2 = projectPath3(options.projectRoot, options.modulePath ?? DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE);
21829
21838
  if (!options.force) {
21830
- await access16(path2).then(() => {
21839
+ await access17(path2).then(() => {
21831
21840
  throw new TypeError(`Mobile update registry already exists: ${path2}. Pass --force to replace it.`);
21832
21841
  }, () => {
21833
21842
  return;
@@ -25938,6 +25947,29 @@ var acquireAbsoluteRemoteMacReleaseLease = async (project, options = {}) => {
25938
25947
  release: () => runOwned(`rm -rf ${shellQuote(path)}`)
25939
25948
  };
25940
25949
  };
25950
+ var cleanAbsoluteRemoteMacWorkspace = async (profile, transport) => {
25951
+ const root = profile.workspaceRoot;
25952
+ const projects = posix.join(root, "projects");
25953
+ const script = [
25954
+ "set -eu",
25955
+ `mkdir -p ${shellQuote(root)}`,
25956
+ `project_staging=$(find ${shellQuote(projects)} -mindepth 2 -maxdepth 2 -type d \\( -name '.incoming-*' -o -name '.previous' -o -name '.release-lease.stale-*' \\) -mtime +0 -prune -print 2>/dev/null | wc -l | tr -d ' ')`,
25957
+ `mobile_staging=$(find ${shellQuote(projects)} -type d \\( -path '*/current/.absolutejs/mobile/.ios-build-*' -o -path '*/current/.absolutejs/mobile/.ios-stage-*' -o -path '*/current/.absolutejs/mobile/*.incoming-*' \\) -mtime +0 -prune -print 2>/dev/null | wc -l | tr -d ' ')`,
25958
+ `count=$((project_staging+mobile_staging))`,
25959
+ `find ${shellQuote(projects)} -mindepth 2 -maxdepth 2 -type d \\( -name '.incoming-*' -o -name '.previous' -o -name '.release-lease.stale-*' \\) -mtime +0 -prune -exec rm -rf {} + 2>/dev/null || true`,
25960
+ `find ${shellQuote(projects)} -type d \\( -path '*/current/.absolutejs/mobile/.ios-build-*' -o -path '*/current/.absolutejs/mobile/.ios-stage-*' -o -path '*/current/.absolutejs/mobile/*.incoming-*' \\) -mtime +0 -prune -exec rm -rf {} + 2>/dev/null || true`,
25961
+ `printf '%s\\n' "$count"`
25962
+ ].join("; ");
25963
+ const result = await (transport?.capture ?? defaultTransport.capture)([
25964
+ ...absoluteRemoteMacSshBase(profile),
25965
+ "/bin/sh -lc",
25966
+ shellQuote(script)
25967
+ ]);
25968
+ const removed = Number(requireRemoteSuccess(result, "Remote Mac workspace cleanup"));
25969
+ if (!Number.isSafeInteger(removed) || removed < 0)
25970
+ throw new TypeError("Remote Mac returned an invalid cleanup result.");
25971
+ return { profile: profile.name, removed, workspaceRoot: root };
25972
+ };
25941
25973
  var inspectAbsoluteRemoteMacWorkspace = async (profile, transport) => {
25942
25974
  const root = profile.workspaceRoot;
25943
25975
  const script = [
@@ -25966,29 +25998,6 @@ var inspectAbsoluteRemoteMacWorkspace = async (profile, transport) => {
25966
25998
  workspaceRoot: root
25967
25999
  };
25968
26000
  };
25969
- var cleanAbsoluteRemoteMacWorkspace = async (profile, transport) => {
25970
- const root = profile.workspaceRoot;
25971
- const projects = posix.join(root, "projects");
25972
- const script = [
25973
- "set -eu",
25974
- `mkdir -p ${shellQuote(root)}`,
25975
- `project_staging=$(find ${shellQuote(projects)} -mindepth 2 -maxdepth 2 -type d \\( -name '.incoming-*' -o -name '.previous' -o -name '.release-lease.stale-*' \\) -mtime +0 -prune -print 2>/dev/null | wc -l | tr -d ' ')`,
25976
- `mobile_staging=$(find ${shellQuote(projects)} -type d \\( -path '*/current/.absolutejs/mobile/.ios-build-*' -o -path '*/current/.absolutejs/mobile/.ios-stage-*' -o -path '*/current/.absolutejs/mobile/*.incoming-*' \\) -mtime +0 -prune -print 2>/dev/null | wc -l | tr -d ' ')`,
25977
- `count=$((project_staging+mobile_staging))`,
25978
- `find ${shellQuote(projects)} -mindepth 2 -maxdepth 2 -type d \\( -name '.incoming-*' -o -name '.previous' -o -name '.release-lease.stale-*' \\) -mtime +0 -prune -exec rm -rf {} + 2>/dev/null || true`,
25979
- `find ${shellQuote(projects)} -type d \\( -path '*/current/.absolutejs/mobile/.ios-build-*' -o -path '*/current/.absolutejs/mobile/.ios-stage-*' -o -path '*/current/.absolutejs/mobile/*.incoming-*' \\) -mtime +0 -prune -exec rm -rf {} + 2>/dev/null || true`,
25980
- `printf '%s\\n' "$count"`
25981
- ].join("; ");
25982
- const result = await (transport?.capture ?? defaultTransport.capture)([
25983
- ...absoluteRemoteMacSshBase(profile),
25984
- "/bin/sh -lc",
25985
- shellQuote(script)
25986
- ]);
25987
- const removed = Number(requireRemoteSuccess(result, "Remote Mac workspace cleanup"));
25988
- if (!Number.isSafeInteger(removed) || removed < 0)
25989
- throw new TypeError("Remote Mac returned an invalid cleanup result.");
25990
- return { profile: profile.name, removed, workspaceRoot: root };
25991
- };
25992
26001
  var installAbsoluteRemoteMacAgent = async (project) => {
25993
26002
  const artifact = await materializeAbsoluteRemoteMacAgent(project.projectRoot);
25994
26003
  const directory = posix.join(project.profile.workspaceRoot, "agents", `protocol-${ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION}`, artifact.sha256);
@@ -26334,7 +26343,7 @@ var buildAbsoluteRemoteIosRelease = async (options) => {
26334
26343
  heartbeat = undefined;
26335
26344
  });
26336
26345
  }, REMOTE_RELEASE_LEASE_HEARTBEAT_MS);
26337
- heartbeatTimer.unref();
26346
+ unrefTimer(heartbeatTimer);
26338
26347
  try {
26339
26348
  const syncStartedAt = performance.now();
26340
26349
  if (options.syncProject)
@@ -26477,7 +26486,7 @@ var buildAbsoluteRemoteIosRelease = async (options) => {
26477
26486
  }
26478
26487
  };
26479
26488
  var startAbsoluteRemoteExpoIosDevSession = async (options) => {
26480
- const session = await startAbsoluteRemoteDevSession({
26489
+ let session = await startAbsoluteRemoteDevSession({
26481
26490
  certificateAuthorityPath: options.certificateAuthorityPath,
26482
26491
  deviceIdentifier: options.deviceIdentifier,
26483
26492
  https: options.https,
@@ -26493,12 +26502,18 @@ var startAbsoluteRemoteExpoIosDevSession = async (options) => {
26493
26502
  syncProject: options.syncProject,
26494
26503
  transport: options.transport
26495
26504
  });
26496
- return {
26505
+ const expoSession = {
26497
26506
  close: session.close,
26498
26507
  metroPort: options.metroPort,
26499
26508
  platforms: ["ios"],
26500
- timings: session.timings
26509
+ timings: session.timings,
26510
+ rebuild: async () => {
26511
+ session = await session.rebuild();
26512
+ expoSession.timings = session.timings;
26513
+ return expoSession;
26514
+ }
26501
26515
  };
26516
+ return expoSession;
26502
26517
  };
26503
26518
  var startAbsoluteRemoteIosDevSession = (options) => startAbsoluteRemoteDevSession(options);
26504
26519
  var startAbsoluteRemoteDevSession = async (options) => {
@@ -26836,7 +26851,7 @@ var parseAbsoluteMobileBuildPageMetadata = (value) => {
26836
26851
  };
26837
26852
  // src/mobile/buildPipeline.ts
26838
26853
  import { readFile as readFile15 } from "fs/promises";
26839
- import { join as join16, resolve as resolve13 } from "path";
26854
+ import { join as join17, resolve as resolve13 } from "path";
26840
26855
  import { pathToFileURL as pathToFileURL2 } from "url";
26841
26856
 
26842
26857
  // src/mobile/buildRelease.ts
@@ -27607,7 +27622,7 @@ import {
27607
27622
  writeFile as writeFile12
27608
27623
  } from "fs/promises";
27609
27624
  import { createHash as createHash12 } from "crypto";
27610
- import { basename as basename4, dirname as dirname10, join as join15, relative as relative10, resolve as resolve12, sep as sep6 } from "path";
27625
+ import { basename as basename4, dirname as dirname10, join as join16, relative as relative10, resolve as resolve12, sep as sep6 } from "path";
27611
27626
 
27612
27627
  // src/mobile/updateRuntime.ts
27613
27628
  init_deviceCapabilities();
@@ -28250,6 +28265,127 @@ var absoluteExpoNativeObservabilityPaths = (project) => [
28250
28265
  ...absoluteExpoNativeObservabilityFiles(project).keys()
28251
28266
  ];
28252
28267
 
28268
+ // src/mobile/expoActivityResultRecovery.ts
28269
+ import { join as join15 } from "path";
28270
+ var HEADER2 = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
28271
+ `;
28272
+ var XML_HEADER2 = `<!-- Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync. -->
28273
+ `;
28274
+ var moduleConfig2 = `${JSON.stringify({
28275
+ android: {
28276
+ modules: [
28277
+ "expo.modules.absoluteactivityresultrecovery.AbsoluteActivityResultRecoveryModule"
28278
+ ]
28279
+ },
28280
+ platforms: ["android"]
28281
+ }, null, 2)}
28282
+ `;
28283
+ var androidBuild2 = `${HEADER2}plugins {
28284
+ id 'com.android.library'
28285
+ id 'expo-module-gradle-plugin'
28286
+ }
28287
+
28288
+ group = 'expo.modules.absoluteactivityresultrecovery'
28289
+ version = '0.0.1'
28290
+
28291
+ android {
28292
+ namespace 'expo.modules.absoluteactivityresultrecovery'
28293
+ defaultConfig {
28294
+ versionCode 1
28295
+ versionName '0.0.1'
28296
+ }
28297
+ lintOptions { abortOnError false }
28298
+ }
28299
+ `;
28300
+ var androidManifest2 = `${XML_HEADER2}<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
28301
+ `;
28302
+ var androidModule2 = `${HEADER2}package expo.modules.absoluteactivityresultrecovery
28303
+
28304
+ import android.content.Intent
28305
+ import android.util.Log
28306
+ import expo.modules.kotlin.modules.Module
28307
+ import expo.modules.kotlin.modules.ModuleDefinition
28308
+
28309
+ data class AbsolutePendingActivityResult(
28310
+ val requestCode: Int,
28311
+ val resultCode: Int,
28312
+ val data: Intent?
28313
+ )
28314
+
28315
+ object AbsoluteActivityResultRecoveryState {
28316
+ @Volatile
28317
+ var applicationRuntimeReady = false
28318
+
28319
+ private val pendingActivityResults = ArrayDeque<AbsolutePendingActivityResult>()
28320
+
28321
+ @Synchronized
28322
+ fun enqueueActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
28323
+ if (pendingActivityResults.size == 8) pendingActivityResults.removeFirst()
28324
+ pendingActivityResults.addLast(
28325
+ AbsolutePendingActivityResult(requestCode, resultCode, data?.let(::Intent))
28326
+ )
28327
+ Log.d("AbsoluteJS", "Queued early Android activity result; pending=" + pendingActivityResults.size)
28328
+ }
28329
+
28330
+ @Synchronized
28331
+ fun hasPendingActivityResults() = pendingActivityResults.isNotEmpty()
28332
+
28333
+ @Synchronized
28334
+ fun drainActivityResults(): List<AbsolutePendingActivityResult> {
28335
+ val drained = pendingActivityResults.toList()
28336
+ pendingActivityResults.clear()
28337
+ Log.d("AbsoluteJS", "Replaying queued Android activity results; count=" + drained.size)
28338
+ return drained
28339
+ }
28340
+ }
28341
+
28342
+ class AbsoluteActivityResultRecoveryModule : Module() {
28343
+ override fun definition() = ModuleDefinition {
28344
+ Name("AbsoluteActivityResultRecovery")
28345
+
28346
+ Function("markApplicationRuntimeReady") {
28347
+ AbsoluteActivityResultRecoveryState.applicationRuntimeReady = true
28348
+ Log.d("AbsoluteJS", "Expo application runtime ready for Android activity results")
28349
+ }
28350
+ }
28351
+ }
28352
+ `;
28353
+ var runtime = `${HEADER2}import { requireNativeModule } from 'expo-modules-core';
28354
+
28355
+ type AbsoluteActivityResultRecoveryNative = {
28356
+ markApplicationRuntimeReady(): void;
28357
+ };
28358
+
28359
+ const native = requireNativeModule<AbsoluteActivityResultRecoveryNative>(
28360
+ 'AbsoluteActivityResultRecovery'
28361
+ );
28362
+
28363
+ export const markAbsoluteApplicationRuntimeReady = () =>
28364
+ native.markApplicationRuntimeReady();
28365
+ `;
28366
+ var absoluteExpoActivityResultRecoveryFiles = (project) => new Map([
28367
+ [
28368
+ join15(project, "modules/absolute-activity-result-recovery/expo-module.config.json"),
28369
+ moduleConfig2
28370
+ ],
28371
+ [
28372
+ join15(project, "modules/absolute-activity-result-recovery/android/build.gradle"),
28373
+ androidBuild2
28374
+ ],
28375
+ [
28376
+ join15(project, "modules/absolute-activity-result-recovery/android/src/main/AndroidManifest.xml"),
28377
+ androidManifest2
28378
+ ],
28379
+ [
28380
+ join15(project, "modules/absolute-activity-result-recovery/android/src/main/java/expo/modules/absoluteactivityresultrecovery/AbsoluteActivityResultRecoveryModule.kt"),
28381
+ androidModule2
28382
+ ],
28383
+ [
28384
+ join15(project, "src/generated/AbsoluteActivityResultRecovery.ts"),
28385
+ runtime
28386
+ ]
28387
+ ]);
28388
+
28253
28389
  // src/mobile/expoProject.ts
28254
28390
  var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
28255
28391
  `;
@@ -28330,7 +28466,7 @@ var routeSegments = (route) => {
28330
28466
  return segment;
28331
28467
  });
28332
28468
  };
28333
- var routeFile = (project, route) => join15(project, "app", ...routeSegments(route), "index.tsx");
28469
+ var routeFile = (project, route) => join16(project, "app", ...routeSegments(route), "index.tsx");
28334
28470
  var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map((spec) => {
28335
28471
  const separator = spec.lastIndexOf("@");
28336
28472
  return [spec.slice(0, separator), spec.slice(separator + 1)];
@@ -28338,7 +28474,7 @@ var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map
28338
28474
  var expoPackage = (auth, sync, devices, updates) => ({
28339
28475
  dependencies: {
28340
28476
  "@absolutejs/devices": "0.7.0",
28341
- "@absolutejs/devices-expo": "0.0.2",
28477
+ "@absolutejs/devices-expo": "0.0.9",
28342
28478
  ...auth ? {
28343
28479
  "@absolutejs/auth": ABSOLUTE_EXPO_AUTH_CORE_VERSION,
28344
28480
  [ABSOLUTE_EXPO_AUTH_PACKAGE]: ABSOLUTE_EXPO_AUTH_VERSION
@@ -28474,6 +28610,7 @@ var expoAppConfig = (config, auth, sync, devices, runtimeFingerprint) => {
28474
28610
  plugins: [
28475
28611
  "expo-router",
28476
28612
  ["expo-dev-client", { launchMode: "most-recent" }],
28613
+ "./plugins/withAbsoluteActivityResultRecovery",
28477
28614
  ...auth || config.updates ? ["expo-secure-store"] : [],
28478
28615
  ...sync ? [
28479
28616
  "expo-sqlite",
@@ -28563,6 +28700,77 @@ const withAbsoluteDevelopmentCa = config => {
28563
28700
 
28564
28701
  module.exports = withAbsoluteDevelopmentCa;
28565
28702
  `;
28703
+ var expoActivityResultRecoveryPlugin = `${EXPO_GENERATED_HEADER}const { withMainActivity } = require('expo/config-plugins');
28704
+
28705
+ const IMPORT_ANCHOR = 'import android.os.Bundle';
28706
+ const CLASS_ANCHOR = 'class MainActivity : ReactActivity() {';
28707
+ const RECOVERY_MARKER = 'absolutePendingActivityResults';
28708
+
28709
+ const withAbsoluteActivityResultRecovery = config => withMainActivity(config, value => {
28710
+ if (value.modResults.language !== 'kt') {
28711
+ throw new Error('AbsoluteJS Expo activity-result recovery requires a Kotlin MainActivity.');
28712
+ }
28713
+ let source = value.modResults.contents;
28714
+ if (source.includes(RECOVERY_MARKER)) return value;
28715
+ if (!source.includes(IMPORT_ANCHOR) || !source.includes(CLASS_ANCHOR)) {
28716
+ throw new Error('AbsoluteJS could not locate the Expo MainActivity integration points.');
28717
+ }
28718
+ source = source.replace(IMPORT_ANCHOR, [
28719
+ 'import android.content.Intent',
28720
+ 'import android.os.Bundle',
28721
+ 'import android.os.Handler',
28722
+ 'import android.os.Looper',
28723
+ 'import expo.modules.absoluteactivityresultrecovery.AbsoluteActivityResultRecoveryState'
28724
+ ].join('\\n'));
28725
+ source = source.replace(CLASS_ANCHOR, \`\${CLASS_ANCHOR}
28726
+ private val absoluteActivityResultHandler = Handler(Looper.getMainLooper())
28727
+ private var absoluteActivityResultAttempts = 0
28728
+ private val absoluteReplayActivityResults = object : Runnable {
28729
+ override fun run() {
28730
+ if (isFinishing || isDestroyed || !AbsoluteActivityResultRecoveryState.hasPendingActivityResults()) return
28731
+ if (!AbsoluteActivityResultRecoveryState.applicationRuntimeReady) {
28732
+ if (absoluteActivityResultAttempts++ < 240) {
28733
+ absoluteActivityResultHandler.postDelayed(this, 250)
28734
+ }
28735
+ return
28736
+ }
28737
+ absoluteActivityResultAttempts = 0
28738
+ AbsoluteActivityResultRecoveryState.drainActivityResults().forEach { result ->
28739
+ super@MainActivity.onActivityResult(result.requestCode, result.resultCode, result.data)
28740
+ }
28741
+ }
28742
+ }
28743
+
28744
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
28745
+ if (AbsoluteActivityResultRecoveryState.applicationRuntimeReady) {
28746
+ super.onActivityResult(requestCode, resultCode, data)
28747
+ return
28748
+ }
28749
+ AbsoluteActivityResultRecoveryState.enqueueActivityResult(requestCode, resultCode, data)
28750
+ absoluteActivityResultHandler.removeCallbacks(absoluteReplayActivityResults)
28751
+ absoluteActivityResultHandler.postDelayed(absoluteReplayActivityResults, 250)
28752
+ }
28753
+
28754
+ override fun onResume() {
28755
+ super.onResume()
28756
+ if (AbsoluteActivityResultRecoveryState.hasPendingActivityResults()) {
28757
+ absoluteActivityResultAttempts = 0
28758
+ absoluteActivityResultHandler.removeCallbacks(absoluteReplayActivityResults)
28759
+ absoluteActivityResultHandler.post(absoluteReplayActivityResults)
28760
+ }
28761
+ }
28762
+
28763
+ override fun onDestroy() {
28764
+ absoluteActivityResultHandler.removeCallbacks(absoluteReplayActivityResults)
28765
+ super.onDestroy()
28766
+ }
28767
+ \`);
28768
+ value.modResults.contents = source;
28769
+ return value;
28770
+ });
28771
+
28772
+ module.exports = withAbsoluteActivityResultRecovery;
28773
+ `;
28566
28774
  var metroConfig = (projectRoot) => `${EXPO_GENERATED_HEADER}const { getDefaultConfig } = require('expo/metro-config');
28567
28775
  const path = require('node:path');
28568
28776
 
@@ -28580,6 +28788,8 @@ module.exports = config;
28580
28788
  `;
28581
28789
  var layoutSource = (auth, sync, updates, observability) => `${EXPO_GENERATED_HEADER}import { Stack } from 'expo-router';
28582
28790
  import '../src/generated/AbsoluteDevices';
28791
+ import { useEffect as useActivityResultRecoveryEffect } from 'react';
28792
+ import { markAbsoluteApplicationRuntimeReady } from '../src/generated/AbsoluteActivityResultRecovery';
28583
28793
  ${auth ? `import { useEffect, useState } from 'react';
28584
28794
  import { startAbsoluteExpoAuth } from '../src/generated/AbsoluteAuth';` : ""}
28585
28795
  ${sync ? "import { startAbsoluteExpoSync } from '../src/generated/AbsoluteSync';" : ""}
@@ -28589,6 +28799,9 @@ ${observability ? `import { useEffect as useNativeObservabilityEffect } from 're
28589
28799
  import { startAbsoluteExpoNativeObservability } from '../src/generated/AbsoluteNativeObservability';` : ""}
28590
28800
 
28591
28801
  export default function AbsoluteLayout() {
28802
+ useActivityResultRecoveryEffect(() => {
28803
+ markAbsoluteApplicationRuntimeReady();
28804
+ }, []);
28592
28805
  ${updates ? "useUpdateEffect(() => { void startAbsoluteExpoUpdates(); }, []);" : ""}
28593
28806
  ${observability ? "useNativeObservabilityEffect(() => { void startAbsoluteExpoNativeObservability(); }, []);" : ""}
28594
28807
  ${auth ? `const [ready, setReady] = useState(false);
@@ -28945,7 +29158,7 @@ var webHostSource = (config, auth, sync) => {
28945
29158
  const nativeRoutePatterns = nativeRoutes.map((route) => route.split("/").filter(Boolean));
28946
29159
  return `${EXPO_GENERATED_HEADER}import * as Linking from 'expo-linking';
28947
29160
  import { router, usePathname } from 'expo-router';
28948
- import { useEffect, useRef, useState } from 'react';
29161
+ import { useEffect, useMemo, useRef, useState } from 'react';
28949
29162
  import { ActivityIndicator, BackHandler, Platform, StyleSheet, View } from 'react-native';
28950
29163
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
28951
29164
  import { WebView, type WebViewMessageEvent } from 'react-native-webview';
@@ -29100,17 +29313,21 @@ const authStatus = async () => {
29100
29313
  return { principal: principal ? { namespace: principal.namespace } : null, user };` : "throw new Error('Expo Auth is not configured.');"}
29101
29314
  };
29102
29315
 
29103
- export function AbsoluteWebHost() {
29104
- const pathname = usePathname() || '/';
29316
+ export type AbsoluteWebHostProps = { path?: string };
29317
+
29318
+ export function AbsoluteWebHost({ path }: AbsoluteWebHostProps = {}) {
29319
+ const routerPathname = usePathname() || '/';
29320
+ const pathname = path?.startsWith('/') && !path.startsWith('//') ? path : routerPathname;
29105
29321
  const safeAreaInsets = useSafeAreaInsets();
29106
29322
  const webView = useRef<WebView>(null);
29107
29323
  const devicesBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
29108
29324
  const syncBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
29109
29325
  const [indexUri, setIndexUri] = useState<string>();
29110
- const [canGoBack, setCanGoBack] = useState(false);
29326
+ const canGoBack = useRef(false);
29111
29327
  const [runtimeReady, setRuntimeReady] = useState(!AUTH_ENABLED && !SYNC_ENABLED);
29112
29328
  const [devicesReady, setDevicesReady] = useState(false);
29113
29329
  const activeWebPath = useRef(pathname);
29330
+ const webSource = useMemo(() => indexUri ? { uri: indexUri } : undefined, [indexUri]);
29114
29331
 
29115
29332
  useEffect(() => {
29116
29333
  if (!AUTH_ENABLED && !SYNC_ENABLED) return;
@@ -29168,7 +29385,7 @@ export function AbsoluteWebHost() {
29168
29385
  if (!active) return;
29169
29386
  respond({ event, format: BRIDGE_FORMAT, kind: 'event', path: activeWebPath.current, payload });
29170
29387
  }).then(host => {
29171
- if (!active) return void host.close();
29388
+ if (!active) return void Promise.resolve(host.close()).catch(() => undefined);
29172
29389
  devicesBridge.current = host;
29173
29390
  setDevicesReady(true);
29174
29391
  });
@@ -29176,7 +29393,7 @@ export function AbsoluteWebHost() {
29176
29393
  active = false;
29177
29394
  const host = devicesBridge.current;
29178
29395
  devicesBridge.current = undefined;
29179
- void host?.close();
29396
+ if (host) void Promise.resolve(host.close()).catch(() => undefined);
29180
29397
  };
29181
29398
  }, []);
29182
29399
  const hasOrigin = (source: string, origin: string) => {
@@ -29196,7 +29413,7 @@ export function AbsoluteWebHost() {
29196
29413
  return;
29197
29414
  }
29198
29415
  if (message.kind === 'event' && message.event === 'back-unhandled') {
29199
- if (canGoBack) webView.current?.goBack();
29416
+ if (canGoBack.current) webView.current?.goBack();
29200
29417
  else BackHandler.exitApp();
29201
29418
  return;
29202
29419
  }
@@ -29230,22 +29447,27 @@ export function AbsoluteWebHost() {
29230
29447
  }
29231
29448
  };
29232
29449
 
29233
- if (!indexUri || !runtimeReady || !devicesReady) return <View style={styles.loading}><ActivityIndicator /></View>;
29450
+ if (!webSource || !runtimeReady || !devicesReady) return <View style={styles.loading}><ActivityIndicator /></View>;
29234
29451
  return <WebView
29235
29452
  allowFileAccess
29236
29453
  allowFileAccessFromFileURLs
29237
29454
  allowUniversalAccessFromFileURLs={false}
29238
- allowingReadAccessToURL={indexUri.slice(0, indexUri.lastIndexOf('/') + 1)}
29455
+ allowingReadAccessToURL={webSource.uri.slice(0, webSource.uri.lastIndexOf('/') + 1)}
29239
29456
  injectedJavaScriptBeforeContentLoaded={bridgeBootstrap(pathname, safeAreaInsets)}
29240
29457
  onMessage={onMessage}
29241
- onNavigationStateChange={state => setCanGoBack(state.canGoBack)}
29458
+ onNavigationStateChange={state => {
29459
+ canGoBack.current = state.canGoBack;
29460
+ if (!DEV_ORIGIN || !hasOrigin(state.url, DEV_ORIGIN)) return;
29461
+ const route = new URL(state.url);
29462
+ activeWebPath.current = route.pathname + route.search + route.hash;
29463
+ }}
29242
29464
  onShouldStartLoadWithRequest={request => {
29243
29465
  if (request.url.startsWith('file:') || hasOrigin(request.url, PRODUCTION_ORIGIN) || DEV_ORIGIN && hasOrigin(request.url, DEV_ORIGIN)) return true;
29244
29466
  void Linking.openURL(request.url);
29245
29467
  return false;
29246
29468
  }}
29247
29469
  ref={webView}
29248
- source={{ uri: indexUri }}
29470
+ source={webSource}
29249
29471
  style={styles.web}
29250
29472
  />;
29251
29473
  }
@@ -29444,8 +29666,8 @@ const styles = StyleSheet.create({
29444
29666
  error: { color: '#b91c1c', fontSize: 16, textAlign: 'center' }
29445
29667
  });
29446
29668
  `;
29447
- var nativeWrapperSource = (wrapper, module, runtime, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative2(dirname10(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
29448
- import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative2(dirname10(wrapper), runtime).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
29669
+ var nativeWrapperSource = (wrapper, module, runtime2, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative2(dirname10(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
29670
+ import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative2(dirname10(wrapper), runtime2).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
29449
29671
 
29450
29672
  export const ErrorBoundary = createAbsoluteNativeRouteErrorBoundary(${JSON.stringify(route)});
29451
29673
  export default createAbsoluteNativeRoute(ApplicationNativeRoute, ${JSON.stringify(route)});
@@ -29514,7 +29736,7 @@ var pruneManagedFiles = async (paths) => {
29514
29736
  return removed.filter(Boolean).length;
29515
29737
  };
29516
29738
  var pruneStaleManagedExpoRoutes = async (project, expected) => {
29517
- const appDirectory = join15(project, "app");
29739
+ const appDirectory = join16(project, "app");
29518
29740
  if (!await exists3(appDirectory))
29519
29741
  return 0;
29520
29742
  const files = await walkFiles(appDirectory);
@@ -29562,7 +29784,7 @@ var writeAbsoluteExpoProject = async (config, options) => {
29562
29784
  if (missing) {
29563
29785
  throw new TypeError(`Expo native route ${missing.route} references missing module ${missing.module}.`);
29564
29786
  }
29565
- const marker = join15(project, EXPO_PROJECT_MARKER);
29787
+ const marker = join16(project, EXPO_PROJECT_MARKER);
29566
29788
  if (await exists3(project) && !await exists3(marker)) {
29567
29789
  const entries = await readdir4(project);
29568
29790
  if (entries.length > 0 && !options.force) {
@@ -29575,7 +29797,7 @@ var writeAbsoluteExpoProject = async (config, options) => {
29575
29797
  const authEnabled = Boolean(auth);
29576
29798
  const files = new Map([
29577
29799
  [
29578
- join15(project, ".gitignore"),
29800
+ join16(project, ".gitignore"),
29579
29801
  `.expo/
29580
29802
  android/
29581
29803
  ios/
@@ -29583,74 +29805,80 @@ node_modules/
29583
29805
  `
29584
29806
  ],
29585
29807
  [
29586
- join15(project, "app.json"),
29808
+ join16(project, "app.json"),
29587
29809
  jsonSource(expoAppConfig(config, authEnabled, syncEnabled, devices, runtimeFingerprint))
29588
29810
  ],
29589
- [join15(project, "app.config.js"), expoDynamicAppConfig],
29811
+ [join16(project, "app.config.js"), expoDynamicAppConfig],
29590
29812
  [
29591
- join15(project, "package.json"),
29813
+ join16(project, "package.json"),
29592
29814
  jsonSource(expoPackage(authEnabled, syncEnabled, devices, config.updates !== undefined))
29593
29815
  ],
29594
- [join15(project, "metro.config.js"), metroConfig(projectRoot)],
29816
+ [join16(project, "metro.config.js"), metroConfig(projectRoot)],
29595
29817
  [
29596
- join15(project, "plugins", "withAbsoluteDevelopmentCa.js"),
29818
+ join16(project, "plugins", "withAbsoluteDevelopmentCa.js"),
29597
29819
  expoDevelopmentCaPlugin
29598
29820
  ],
29599
29821
  [
29600
- join15(project, "tsconfig.json"),
29822
+ join16(project, "plugins", "withAbsoluteActivityResultRecovery.js"),
29823
+ expoActivityResultRecoveryPlugin
29824
+ ],
29825
+ [
29826
+ join16(project, "tsconfig.json"),
29601
29827
  jsonSource(expoTsConfig(projectRoot, project, authEnabled, syncEnabled))
29602
29828
  ],
29603
29829
  [
29604
- join15(project, "app", "_layout.tsx"),
29830
+ join16(project, "app", "_layout.tsx"),
29605
29831
  layoutSource(authEnabled, syncEnabled, config.updates !== undefined, config.observability !== undefined)
29606
29832
  ],
29607
29833
  [
29608
- join15(project, "app", "__absolute", "native", "index.tsx"),
29834
+ join16(project, "app", "__absolute", "native", "index.tsx"),
29609
29835
  nativeDiagnosticSource
29610
29836
  ],
29611
29837
  [
29612
- join15(project, "src", "generated", "AbsoluteDevices.ts"),
29838
+ join16(project, "src", "generated", "AbsoluteDevices.ts"),
29613
29839
  devicesRuntimeSource(config, devices, authEnabled)
29614
29840
  ],
29615
29841
  [
29616
- join15(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
29842
+ join16(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
29617
29843
  nativeRouteRuntimeSource(authEnabled)
29618
29844
  ],
29619
29845
  [
29620
- join15(project, "src", "generated", "AbsoluteWebHost.tsx"),
29846
+ join16(project, "src", "generated", "AbsoluteWebHost.tsx"),
29621
29847
  webHostSource(config, auth, syncEnabled)
29622
29848
  ]
29623
29849
  ]);
29850
+ for (const [path, source] of absoluteExpoActivityResultRecoveryFiles(project))
29851
+ files.set(path, source);
29624
29852
  if (config.observability) {
29625
29853
  for (const [path, source] of absoluteExpoNativeObservabilityFiles(project))
29626
29854
  files.set(path, source);
29627
29855
  }
29628
29856
  if (config.updates) {
29629
- files.set(join15(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
29857
+ files.set(join16(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
29630
29858
  }
29631
29859
  const expoCodeSigning = config.updates?.expoCodeSigning;
29632
29860
  if (expoCodeSigning)
29633
- files.set(join15(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
29861
+ files.set(join16(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
29634
29862
  if (auth) {
29635
- files.set(join15(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
29863
+ files.set(join16(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
29636
29864
  }
29637
29865
  if (syncSchema) {
29638
- files.set(join15(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
29866
+ files.set(join16(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
29639
29867
  }
29640
- const webAssetsPath = join15(project, "src", "generated", "webAssets.ts");
29868
+ const webAssetsPath = join16(project, "src", "generated", "webAssets.ts");
29641
29869
  if (!await exists3(webAssetsPath)) {
29642
29870
  files.set(webAssetsPath, emptyWebAssetsSource);
29643
29871
  }
29644
29872
  if (!config.expoNativeRoutes["/"]) {
29645
- files.set(join15(project, "app", "index.tsx"), webRouteSource);
29873
+ files.set(join16(project, "app", "index.tsx"), webRouteSource);
29646
29874
  }
29647
- files.set(join15(project, "app", "[...absolute].tsx"), catchAllRouteSource);
29648
- const nativeRouteRuntime = join15(project, "src", "generated", "AbsoluteNativeRoute.tsx");
29875
+ files.set(join16(project, "app", "[...absolute].tsx"), catchAllRouteSource);
29876
+ const nativeRouteRuntime = join16(project, "src", "generated", "AbsoluteNativeRoute.tsx");
29649
29877
  for (const [route, module] of routeModules) {
29650
- const wrapper = route === "/" ? join15(project, "app", "index.tsx") : routeFile(project, route);
29878
+ const wrapper = route === "/" ? join16(project, "app", "index.tsx") : routeFile(project, route);
29651
29879
  files.set(wrapper, nativeWrapperSource(wrapper, module, nativeRouteRuntime, route));
29652
29880
  }
29653
- const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join15(project, "app")}${sep6}`))));
29881
+ const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join16(project, "app")}${sep6}`))));
29654
29882
  const removedObservability = config.observability ? 0 : await pruneManagedFiles(absoluteExpoNativeObservabilityPaths(project));
29655
29883
  const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
29656
29884
  const changed = removedRoutes + removedObservability + changes.filter(Boolean).length;
@@ -29659,7 +29887,7 @@ node_modules/
29659
29887
  var walkFiles = async (root, directory = root) => {
29660
29888
  const entries = await readdir4(directory, { withFileTypes: true });
29661
29889
  const nested = await Promise.all(entries.map((entry) => {
29662
- const path = join15(directory, entry.name);
29890
+ const path = join16(directory, entry.name);
29663
29891
  if (entry.isDirectory())
29664
29892
  return walkFiles(root, path);
29665
29893
  if (entry.isFile())
@@ -29726,11 +29954,11 @@ export const materializeAbsoluteWebBundle = async () => {
29726
29954
  var syncAbsoluteExpoWebAssets = async (config) => {
29727
29955
  if (config.engine !== "expo")
29728
29956
  throw new TypeError("Expo asset sync requires mobile.engine: expo.");
29729
- const marker = join15(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
29957
+ const marker = join16(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
29730
29958
  if (!await exists3(marker)) {
29731
29959
  throw new TypeError("Expo asset sync requires an AbsoluteJS-managed Expo project. Run mobile init first.");
29732
29960
  }
29733
- const manifestPath = join15(config.bundleDirectory, "absolute-mobile-manifest.json");
29961
+ const manifestPath = join16(config.bundleDirectory, "absolute-mobile-manifest.json");
29734
29962
  const manifest = JSON.parse(await readFile14(manifestPath, "utf8"));
29735
29963
  const nativeDataManifest = expoNativeDataManifest(manifest);
29736
29964
  const { appBuild } = nativeDataManifest;
@@ -29744,16 +29972,16 @@ var syncAbsoluteExpoWebAssets = async (config) => {
29744
29972
  bundleHash.update("\x00");
29745
29973
  });
29746
29974
  const bundleId = `amexpo_${bundleHash.digest("hex")}`;
29747
- const destination = join15(config.nativeProjectDirectory, "assets", "absolute");
29975
+ const destination = join16(config.nativeProjectDirectory, "assets", "absolute");
29748
29976
  await mkdir11(dirname10(destination), { recursive: true });
29749
- const staging = await mkdtemp7(join15(dirname10(destination), `.${basename4(destination)}.stage-`));
29977
+ const staging = await mkdtemp7(join16(dirname10(destination), `.${basename4(destination)}.stage-`));
29750
29978
  let assets;
29751
29979
  try {
29752
29980
  assets = await Promise.all(files.map(async (source, index) => {
29753
29981
  const name = `${String(index).padStart(6, "0")}${EXPO_ASSET_EXTENSION}`;
29754
- await cp2(source, join15(staging, name));
29982
+ await cp2(source, join16(staging, name));
29755
29983
  return {
29756
- asset: portableRelative2(join15(config.nativeProjectDirectory, "src", "generated"), join15(destination, name)),
29984
+ asset: portableRelative2(join16(config.nativeProjectDirectory, "src", "generated"), join16(destination, name)),
29757
29985
  path: relative10(config.bundleDirectory, source).replaceAll("\\", "/")
29758
29986
  };
29759
29987
  }));
@@ -29762,7 +29990,7 @@ var syncAbsoluteExpoWebAssets = async (config) => {
29762
29990
  await rm10(staging, { force: true, recursive: true });
29763
29991
  throw error;
29764
29992
  }
29765
- const generated = join15(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
29993
+ const generated = join16(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
29766
29994
  await writeManagedFile(generated, assetModuleSource(assets, bundleId, nativeDataManifest), true);
29767
29995
  return { appBuild, assets: assets.length, bundleId, path: destination };
29768
29996
  };
@@ -29803,9 +30031,9 @@ var loadServerApp = async (producerPath) => {
29803
30031
  var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
29804
30032
  const buildDirectory = resolve13(options.buildDirectory);
29805
30033
  const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
29806
- const root = join16(buildDirectory, ".absolutejs", "mobile-compatibility");
30034
+ const root = join17(buildDirectory, ".absolutejs", "mobile-compatibility");
29807
30035
  const [manifestSource, previous] = await Promise.all([
29808
- readFile15(join16(buildDirectory, "manifest.json"), "utf8"),
30036
+ readFile15(join17(buildDirectory, "manifest.json"), "utf8"),
29809
30037
  readAbsoluteMobileMaterializedReleases(root)
29810
30038
  ]);
29811
30039
  const manifest = JSON.parse(manifestSource);
@@ -30006,6 +30234,7 @@ var ABSOLUTE_EXPO_BRIDGE_MAX_BYTES = 64 * 1024;
30006
30234
  var ABSOLUTE_EXPO_BRIDGE_METHODS = [
30007
30235
  "devices.platform.getInfo",
30008
30236
  "devices.lifecycle.getState",
30237
+ "devices.lifecycle.takeRestoredOperations",
30009
30238
  "devices.links.getLaunchUrl",
30010
30239
  "devices.links.openExternal",
30011
30240
  "devices.network.getStatus",
@@ -30290,7 +30519,7 @@ var generateAbsoluteExpoCodeSigning = async (options) => {
30290
30519
  // src/mobile/expoDevController.ts
30291
30520
  import { spawn } from "child_process";
30292
30521
  import { access as access11 } from "fs/promises";
30293
- import { join as join17, resolve as resolvePath4 } from "path";
30522
+ import { join as join18, resolve as resolvePath4 } from "path";
30294
30523
  var METRO_READY_TIMEOUT_MS = 120000;
30295
30524
  var PROCESS_CLOSE_TIMEOUT_MS = 2000;
30296
30525
  var preserveWindowsSubstRealpaths = `
@@ -30483,10 +30712,15 @@ var encodedWindowsExpoAndroidCommand = (project, androidRoot, appId, args, captu
30483
30712
  `$env:NODE_ENV = '${mode === "development" ? "development" : "production"}'`,
30484
30713
  ...preferredDevice ? [] : ["$env:ORG_GRADLE_PROJECT_reactNativeArchitectures = 'x86_64'"],
30485
30714
  "New-Item -ItemType Directory -Force -Path $directory | Out-Null",
30486
- "& 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",
30715
+ "& 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",
30487
30716
  "$copyExit = $LASTEXITCODE",
30488
30717
  "if ($copyExit -ge 8) { exit $copyExit }",
30489
30718
  "Set-Location $directory",
30719
+ "$sourceLock = @('bun.lock', 'bun.lockb') | ForEach-Object { Join-Path $source $_ } | Where-Object { Test-Path $_ } | Select-Object -First 1",
30720
+ "$sourceLockHash = if ($sourceLock) { (Get-FileHash $sourceLock -Algorithm SHA256).Hash } else { 'none' }",
30721
+ "$lockMarker = Join-Path $directory '.absolutejs-source-lock.sha256'",
30722
+ "$priorLockHash = if (Test-Path $lockMarker) { (Get-Content $lockMarker -Raw).Trim() } else { '' }",
30723
+ "if ($priorLockHash -ne $sourceLockHash) { Remove-Item (Join-Path $directory 'bun.lock'), (Join-Path $directory 'bun.lockb') -Force -ErrorAction SilentlyContinue; Set-Content $lockMarker $sourceLockHash -NoNewline }",
30490
30724
  "$bun = (Get-Command bun.exe -ErrorAction Stop).Source",
30491
30725
  "& $bun install",
30492
30726
  "if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }",
@@ -30518,7 +30752,7 @@ var commandEnvironment = (options) => ({
30518
30752
  ...options.metroHost ? { REACT_NATIVE_PACKAGER_HOSTNAME: options.metroHost } : {}
30519
30753
  });
30520
30754
  var absoluteExpoExecutable = async (project) => {
30521
- const executable = join17(project, "node_modules", ".bin", "expo");
30755
+ const executable = join18(project, "node_modules", ".bin", "expo");
30522
30756
  try {
30523
30757
  await access11(executable);
30524
30758
  return executable;
@@ -30681,7 +30915,7 @@ var installAbsoluteExpoAndroidRelease = async (options) => {
30681
30915
  const releaseExit = await runUtilityCommand(run, releaseExecutable, releaseArguments, utilityOptions);
30682
30916
  if (releaseExit !== 0)
30683
30917
  throw new Error(`Expo Android release build exited with status ${releaseExit}.`);
30684
- const adb = options.androidAdb ?? join17(androidRoot, "platform-tools", host3 === "windows" || host3 === "wsl" ? "adb.exe" : "adb");
30918
+ const adb = options.androidAdb ?? join18(androidRoot, "platform-tools", host3 === "windows" || host3 === "wsl" ? "adb.exe" : "adb");
30685
30919
  const serial = host3 === "wsl" ? options.androidDevice ?? capture([adb, "devices"]).stdout.split(/\r?\n/u).flatMap((line) => {
30686
30920
  const match = /^(\S+)\s+device$/u.exec(line.trim());
30687
30921
  return match?.[1] ? [match[1]] : [];
@@ -30915,7 +31149,7 @@ var startAbsoluteExpoDevSession = async (options) => {
30915
31149
  }
30916
31150
  if (platform2 === "android" && host3 !== "wsl") {
30917
31151
  const androidRoot = options.androidRoot ?? process.env.ANDROID_HOME ?? process.env.ANDROID_SDK_ROOT ?? absoluteManagedAndroidSdkRoot(host3);
30918
- const adb = options.androidAdb ?? join17(androidRoot, "platform-tools", host3 === "windows" ? "adb.exe" : "adb");
31152
+ const adb = options.androidAdb ?? join18(androidRoot, "platform-tools", host3 === "windows" ? "adb.exe" : "adb");
30919
31153
  connectLocalExpoAndroid(adb, options.config.appId, options.metroPort, capture, options.androidDevice);
30920
31154
  log("Connected the Expo Android development client to Metro.");
30921
31155
  }
@@ -30992,18 +31226,42 @@ var startAbsoluteExpoDevSession = async (options) => {
30992
31226
  publishTiming("starting-metro", performance.now() - metroStarted);
30993
31227
  await runNativeCommands(nativeCommands);
30994
31228
  setState("ready");
30995
- return {
31229
+ let closed = false;
31230
+ let rebuildQueue = Promise.resolve();
31231
+ const session = {
30996
31232
  metroPort: plan.metroPort,
30997
31233
  platforms: options.platforms,
30998
31234
  timings,
30999
31235
  close: async () => {
31236
+ if (closed)
31237
+ return;
31238
+ closed = true;
31000
31239
  options.signal?.removeEventListener("abort", abort);
31240
+ await rebuildQueue;
31001
31241
  if (metro)
31002
31242
  await stopProcess(metro);
31003
31243
  await closeEnrollmentServer();
31004
31244
  setState("closed");
31245
+ },
31246
+ rebuild: () => {
31247
+ const rebuild = rebuildQueue.then(async () => {
31248
+ if (closed)
31249
+ throw new Error("The Expo development session is closed.");
31250
+ if (prepareCommand)
31251
+ await runPrepareCommand(prepareCommand);
31252
+ await runNativeCommands(nativeCommands);
31253
+ setState("ready");
31254
+ return session;
31255
+ });
31256
+ rebuildQueue = rebuild.then(() => {
31257
+ return;
31258
+ }, () => {
31259
+ return;
31260
+ });
31261
+ return rebuild;
31005
31262
  }
31006
31263
  };
31264
+ return session;
31007
31265
  } catch (error) {
31008
31266
  options.signal?.removeEventListener("abort", abort);
31009
31267
  if (metro)
@@ -31013,9 +31271,139 @@ var startAbsoluteExpoDevSession = async (options) => {
31013
31271
  throw error;
31014
31272
  }
31015
31273
  };
31274
+ // src/mobile/expoNativeWatcher.ts
31275
+ import { watch as watch2 } from "fs";
31276
+ import { access as access12, readdir as readdir5, readFile as readFile16 } from "fs/promises";
31277
+ import { basename as basename5, join as join19, relative as relative12 } from "path";
31278
+ import { createHash as createHash13 } from "crypto";
31279
+ var NATIVE_CHANGE_DEBOUNCE_MS2 = 500;
31280
+ var ROOT_NATIVE_INPUTS2 = new Set([
31281
+ "absolute.config.js",
31282
+ "absolute.config.mjs",
31283
+ "absolute.config.ts",
31284
+ "absolutejs.config.js",
31285
+ "absolutejs.config.mjs",
31286
+ "absolutejs.config.ts",
31287
+ "bun.lock",
31288
+ "bun.lockb",
31289
+ "package.json"
31290
+ ]);
31291
+ var EXPO_NATIVE_DIRECTORIES = ["modules", "plugins"];
31292
+ var exists5 = async (path) => access12(path).then(() => true, () => false);
31293
+ var filesIn = async (directory, prefix) => {
31294
+ if (!await exists5(directory))
31295
+ return [];
31296
+ const entries = await readdir5(directory, { withFileTypes: true });
31297
+ const nested = await Promise.all(entries.map((entry) => {
31298
+ const path = join19(directory, entry.name);
31299
+ const name = `${prefix}/${entry.name}`;
31300
+ if (entry.isDirectory())
31301
+ return filesIn(path, name);
31302
+ return Promise.resolve(entry.isFile() ? [{ name, path }] : []);
31303
+ }));
31304
+ return nested.flat().sort((left, right) => left.name.localeCompare(right.name));
31305
+ };
31306
+ var fingerprintAbsoluteExpoNativeInputs = async (options) => {
31307
+ const hash = createHash13("sha256");
31308
+ const rootFiles = await Promise.all([...ROOT_NATIVE_INPUTS2].sort().map(async (name) => {
31309
+ const path = join19(options.projectRoot, name);
31310
+ return await exists5(path) ? [{ name: `root/${name}`, path }] : [];
31311
+ }));
31312
+ const nativeFiles = await Promise.all(EXPO_NATIVE_DIRECTORIES.map((name) => filesIn(join19(options.expoProjectDirectory, name), name)));
31313
+ const files = [...rootFiles.flat(), ...nativeFiles.flat()].sort((left, right) => left.name.localeCompare(right.name));
31314
+ const contents = await Promise.all(files.map(({ path }) => readFile16(path)));
31315
+ files.forEach(({ name }, index) => {
31316
+ hash.update(name);
31317
+ hash.update(contents[index] ?? Buffer.alloc(0));
31318
+ });
31319
+ return hash.digest("hex");
31320
+ };
31321
+ var isAbsoluteExpoNativeRootInput = (path) => ROOT_NATIVE_INPUTS2.has(basename5(path));
31322
+ var createAbsoluteExpoNativeWatcher = async (options) => {
31323
+ let fingerprint = await fingerprintAbsoluteExpoNativeInputs(options);
31324
+ let closed = false;
31325
+ let running = false;
31326
+ let timer;
31327
+ let rootInputChanged = false;
31328
+ const changedPaths = new Set;
31329
+ const watchers = [];
31330
+ const debounceMs = options.debounceMs ?? NATIVE_CHANGE_DEBOUNCE_MS2;
31331
+ const close = () => {
31332
+ if (closed)
31333
+ return;
31334
+ closed = true;
31335
+ if (timer)
31336
+ clearTimeout(timer);
31337
+ watchers.forEach((watcher) => watcher.close());
31338
+ options.signal?.removeEventListener("abort", close);
31339
+ };
31340
+ const schedule = () => {
31341
+ if (closed || running)
31342
+ return;
31343
+ if (timer)
31344
+ clearTimeout(timer);
31345
+ timer = setTimeout(() => void flush(), debounceMs);
31346
+ };
31347
+ const record = (path, root) => {
31348
+ if (closed)
31349
+ return;
31350
+ changedPaths.add(path);
31351
+ rootInputChanged ||= root;
31352
+ schedule();
31353
+ };
31354
+ const flush = async () => {
31355
+ timer = undefined;
31356
+ if (closed || running || changedPaths.size === 0)
31357
+ return;
31358
+ running = true;
31359
+ const paths = [...changedPaths].sort();
31360
+ const rootChanged = rootInputChanged;
31361
+ changedPaths.clear();
31362
+ rootInputChanged = false;
31363
+ try {
31364
+ const next = await fingerprintAbsoluteExpoNativeInputs(options);
31365
+ if (next === fingerprint)
31366
+ return;
31367
+ await options.onChange({
31368
+ afterFingerprint: next,
31369
+ beforeFingerprint: fingerprint,
31370
+ paths,
31371
+ rootInputChanged: rootChanged
31372
+ });
31373
+ fingerprint = await fingerprintAbsoluteExpoNativeInputs(options);
31374
+ } catch (error) {
31375
+ options.onError?.(error);
31376
+ } finally {
31377
+ running = false;
31378
+ if (changedPaths.size > 0)
31379
+ schedule();
31380
+ }
31381
+ };
31382
+ const nativeDirectories = (await Promise.all(EXPO_NATIVE_DIRECTORIES.map(async (name) => {
31383
+ const directory = join19(options.expoProjectDirectory, name);
31384
+ return await exists5(directory) ? [directory] : [];
31385
+ }))).flat();
31386
+ nativeDirectories.forEach((directory) => {
31387
+ watchers.push(watch2(directory, { recursive: true }, (_event, filename) => {
31388
+ if (!filename)
31389
+ return;
31390
+ record(relative12(options.expoProjectDirectory, join19(directory, String(filename))), false);
31391
+ }));
31392
+ });
31393
+ watchers.push(watch2(options.projectRoot, (_event, filename) => {
31394
+ if (!filename)
31395
+ return;
31396
+ const path = String(filename);
31397
+ if (isAbsoluteExpoNativeRootInput(path))
31398
+ record(path, true);
31399
+ }));
31400
+ watchers.forEach((watcher) => watcher.on("error", (error) => options.onError?.(error)));
31401
+ options.signal?.addEventListener("abort", close, { once: true });
31402
+ return { close };
31403
+ };
31016
31404
  // src/mobile/expoUpdate.ts
31017
- import { access as access12, mkdir as mkdir13, readFile as readFile16, writeFile as writeFile14 } from "fs/promises";
31018
- import { dirname as dirname12, extname as extname4, join as join18 } from "path";
31405
+ import { access as access13, mkdir as mkdir13, readFile as readFile17, writeFile as writeFile14 } from "fs/promises";
31406
+ import { dirname as dirname12, extname as extname4, join as join20 } from "path";
31019
31407
  var ABSOLUTE_EXPO_UPDATE_DESCRIPTOR = "_absolute/expo-update.json";
31020
31408
  var ABSOLUTE_EXPO_UPDATE_FORMAT = 1;
31021
31409
  var object4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -31081,7 +31469,7 @@ var parseAbsoluteExpoUpdateDescriptor = (value) => {
31081
31469
  };
31082
31470
  };
31083
31471
  var finalizeAbsoluteExpoUpdateExport = async (options) => {
31084
- const metadata = JSON.parse(await readFile16(join18(options.exportDirectory, "metadata.json"), "utf8"));
31472
+ const metadata = JSON.parse(await readFile17(join20(options.exportDirectory, "metadata.json"), "utf8"));
31085
31473
  if (!object4(metadata) || !object4(metadata.fileMetadata))
31086
31474
  throw new TypeError("Expo export metadata.json is invalid.");
31087
31475
  const descriptor = parseAbsoluteExpoUpdateDescriptor({
@@ -31092,10 +31480,10 @@ var finalizeAbsoluteExpoUpdateExport = async (options) => {
31092
31480
  runtimeVersion: options.runtimeVersion
31093
31481
  });
31094
31482
  const referenced = Object.values(descriptor.platforms).flatMap((entry) => entry ? [entry.launchAsset, ...entry.assets] : []);
31095
- await Promise.all(referenced.map(({ path }) => access12(join18(options.exportDirectory, path)).catch(() => {
31483
+ await Promise.all(referenced.map(({ path }) => access13(join20(options.exportDirectory, path)).catch(() => {
31096
31484
  throw new TypeError(`Expo export metadata references missing asset ${path}.`);
31097
31485
  })));
31098
- const destination = join18(options.exportDirectory, ABSOLUTE_EXPO_UPDATE_DESCRIPTOR);
31486
+ const destination = join20(options.exportDirectory, ABSOLUTE_EXPO_UPDATE_DESCRIPTOR);
31099
31487
  await mkdir13(dirname12(destination), { recursive: true });
31100
31488
  await writeFile14(destination, `${JSON.stringify(descriptor, null, "\t")}
31101
31489
  `);
@@ -31107,8 +31495,8 @@ init_config();
31107
31495
 
31108
31496
  // src/mobile/ciWorkflow.ts
31109
31497
  import { existsSync as existsSync4 } from "fs";
31110
- import { access as access13, mkdir as mkdir14, readFile as readFile17, writeFile as writeFile15 } from "fs/promises";
31111
- import { dirname as dirname13, extname as extname5, relative as relative12, resolve as resolve15, sep as sep8 } from "path";
31498
+ import { access as access14, mkdir as mkdir14, readFile as readFile18, writeFile as writeFile15 } from "fs/promises";
31499
+ import { dirname as dirname13, extname as extname5, relative as relative13, resolve as resolve15, sep as sep8 } from "path";
31112
31500
  var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1;
31113
31501
  var SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
31114
31502
  var CI_ENV_INDENTATION = 6;
@@ -31127,9 +31515,9 @@ var RESERVED_SECRET_NAMES = new Set([
31127
31515
  "APP_STORE_CONNECT_KEY_ID",
31128
31516
  "APP_STORE_CONNECT_PRIVATE_KEY_BASE64"
31129
31517
  ]);
31130
- var exists5 = async (path) => {
31518
+ var exists6 = async (path) => {
31131
31519
  try {
31132
- await access13(path);
31520
+ await access14(path);
31133
31521
  return true;
31134
31522
  } catch {
31135
31523
  return false;
@@ -31139,7 +31527,7 @@ var yamlString = (value) => `'${value.replaceAll("'", "''")}'`;
31139
31527
  var projectPath = (projectRoot, value, field2, options = {}) => {
31140
31528
  const root = resolve15(projectRoot);
31141
31529
  const path = resolve15(root, value);
31142
- const portable = relative12(root, path).replaceAll("\\", "/");
31530
+ const portable = relative13(root, path).replaceAll("\\", "/");
31143
31531
  if (portable === ".." || portable.startsWith(`..${sep8}`) || portable.startsWith("../") || portable === "") {
31144
31532
  throw new TypeError(`${field2} must remain inside the project root.`);
31145
31533
  }
@@ -31153,7 +31541,7 @@ var workflowOutputPath = (projectRoot, value) => {
31153
31541
  const root = resolve15(projectRoot);
31154
31542
  const workflows = resolve15(root, ".github/workflows");
31155
31543
  const path = resolve15(root, value ?? ".github/workflows/absolute-mobile.yml");
31156
- const portable = relative12(workflows, path);
31544
+ const portable = relative13(workflows, path);
31157
31545
  if (portable === ".." || portable.startsWith(`..${sep8}`) || extname5(path) !== ".yml" && extname5(path) !== ".yaml") {
31158
31546
  throw new TypeError("mobile ci github --output must be a .yml or .yaml file inside .github/workflows.");
31159
31547
  }
@@ -31583,9 +31971,9 @@ ${bundleAuditSteps}${platforms.includes("android") ? androidJob({ customSecrets,
31583
31971
  var writeAbsoluteMobileGithubWorkflow = async (options) => {
31584
31972
  const path = workflowOutputPath(options.projectRoot, options.outputPath);
31585
31973
  const generated = createAbsoluteMobileGithubWorkflow(options);
31586
- const previous = await exists5(path) ? await readFile17(path, "utf8") : undefined;
31974
+ const previous = await exists6(path) ? await readFile18(path, "utf8") : undefined;
31587
31975
  if (previous !== undefined && previous !== generated.workflow && !options.force)
31588
- throw new TypeError(`${relative12(options.projectRoot, path)} already exists and differs. Rerun with --force to replace the generated workflow.`);
31976
+ throw new TypeError(`${relative13(options.projectRoot, path)} already exists and differs. Rerun with --force to replace the generated workflow.`);
31589
31977
  if (previous !== generated.workflow) {
31590
31978
  await mkdir14(dirname13(path), { recursive: true });
31591
31979
  await writeFile15(path, generated.workflow);
@@ -31606,15 +31994,15 @@ init_materializedBundle();
31606
31994
  init_mobilePreview();
31607
31995
 
31608
31996
  // src/mobile/nativeDeepLinks.ts
31609
- import { readFile as readFile18, rename as rename12, writeFile as writeFile16 } from "fs/promises";
31610
- import { join as join21 } from "path";
31997
+ import { readFile as readFile19, rename as rename12, writeFile as writeFile16 } from "fs/promises";
31998
+ import { join as join23 } from "path";
31611
31999
  var START_MARKER = "<!-- absolutejs:deep-links:start -->";
31612
32000
  var END_MARKER = "<!-- absolutejs:deep-links:end -->";
31613
32001
  var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
31614
32002
  var NOT_FOUND = -1;
31615
32003
  var escapeXml = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
31616
32004
  var writeChangedFile = async (path, source) => {
31617
- const current = await readFile18(path, "utf8");
32005
+ const current = await readFile19(path, "utf8");
31618
32006
  if (current === source)
31619
32007
  return false;
31620
32008
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
@@ -31664,8 +32052,8 @@ ${hosts}
31664
32052
  `;
31665
32053
  };
31666
32054
  var configureAndroid = async (config) => {
31667
- const path = join21(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
31668
- const source = await readFile18(path, "utf8");
32055
+ const path = join23(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
32056
+ const source = await readFile19(path, "utf8");
31669
32057
  const mainActivity = source.indexOf('android:name=".MainActivity"');
31670
32058
  if (mainActivity === NOT_FOUND) {
31671
32059
  throw new TypeError("Android MainActivity was not found.");
@@ -31690,8 +32078,8 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
31690
32078
  ${END_MARKER}
31691
32079
  `;
31692
32080
  var configureIosInfo = async (config) => {
31693
- const path = join21(config.nativeProjectDirectory, "ios/App/App/Info.plist");
31694
- const source = await readFile18(path, "utf8");
32081
+ const path = join23(config.nativeProjectDirectory, "ios/App/App/Info.plist");
32082
+ const source = await readFile19(path, "utf8");
31695
32083
  const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
31696
32084
  ${END_MARKER}
31697
32085
  `;
@@ -31714,10 +32102,10 @@ ${domains}
31714
32102
  `;
31715
32103
  };
31716
32104
  var configureIosEntitlements = async (config) => {
31717
- const path = join21(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
32105
+ const path = join23(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
31718
32106
  let current = "";
31719
32107
  try {
31720
- current = await readFile18(path, "utf8");
32108
+ current = await readFile19(path, "utf8");
31721
32109
  } catch (error) {
31722
32110
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
31723
32111
  throw error;
@@ -31732,8 +32120,8 @@ var configureIosEntitlements = async (config) => {
31732
32120
  return true;
31733
32121
  };
31734
32122
  var configureIosProject = async (config) => {
31735
- const path = join21(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
31736
- const source = await readFile18(path, "utf8");
32123
+ const path = join23(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
32124
+ const source = await readFile19(path, "utf8");
31737
32125
  const declarations = [
31738
32126
  ...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
31739
32127
  ].map((match) => match[1]);
@@ -31772,8 +32160,8 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
31772
32160
  };
31773
32161
  // src/mobile/nativeDeviceCapabilities.ts
31774
32162
  init_deviceCapabilities();
31775
- import { readFile as readFile19, rename as rename13, writeFile as writeFile17 } from "fs/promises";
31776
- import { join as join22 } from "path";
32163
+ import { readFile as readFile20, rename as rename13, writeFile as writeFile17 } from "fs/promises";
32164
+ import { join as join24 } from "path";
31777
32165
  var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
31778
32166
  var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
31779
32167
  var NOT_FOUND2 = -1;
@@ -31783,7 +32171,7 @@ var PUSH_START_MARKER = "absolutejs:push-notifications:start";
31783
32171
  var PUSH_END_MARKER = "absolutejs:push-notifications:end";
31784
32172
  var escapeXml2 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
31785
32173
  var writeChangedFile2 = async (path, source) => {
31786
- const current = await readFile19(path, "utf8");
32174
+ const current = await readFile20(path, "utf8");
31787
32175
  if (current === source)
31788
32176
  return false;
31789
32177
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
@@ -31803,7 +32191,7 @@ var writeOptionalChangedFile = async (path, source) => {
31803
32191
  };
31804
32192
  var optionalSource = async (path) => {
31805
32193
  try {
31806
- return await readFile19(path, "utf8");
32194
+ return await readFile20(path, "utf8");
31807
32195
  } catch (error) {
31808
32196
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
31809
32197
  return null;
@@ -31923,8 +32311,8 @@ var writeIosPrivacyManifest = async (path, current, source) => {
31923
32311
  var configureIosPrivacyProject = async (config, requirements) => {
31924
32312
  if (requirements.iosPrivacyAccessedApis.length === 0)
31925
32313
  return false;
31926
- const projectPath2 = join22(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
31927
- const project = await readFile19(projectPath2, "utf8");
32314
+ const projectPath2 = join24(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
32315
+ const project = await readFile20(projectPath2, "utf8");
31928
32316
  return writeChangedFile2(projectPath2, addIosPrivacyProjectReference(project));
31929
32317
  };
31930
32318
  var addIosPrivacyProjectReference = (source) => {
@@ -31976,8 +32364,8 @@ ${next.slice(index)}`;
31976
32364
  return next;
31977
32365
  };
31978
32366
  var configureIos2 = async (config, plan) => {
31979
- const path = join22(config.nativeProjectDirectory, "ios/App/App/Info.plist");
31980
- const source = await readFile19(path, "utf8");
32367
+ const path = join24(config.nativeProjectDirectory, "ios/App/App/Info.plist");
32368
+ const source = await readFile20(path, "utf8");
31981
32369
  const requirements = absoluteDeviceNativeRequirements(plan);
31982
32370
  const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
31983
32371
  const ownedStart = source.indexOf(START_MARKER2);
@@ -31997,7 +32385,7 @@ ${content}
31997
32385
  ${END_MARKER2}
31998
32386
  ` : "";
31999
32387
  const infoChanged = await writeChangedFile2(path, managed(source, region, source.lastIndexOf("</dict>")));
32000
- const privacyPath = join22(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
32388
+ const privacyPath = join24(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
32001
32389
  const privacyCurrent = await optionalSource(privacyPath);
32002
32390
  const privacySource = privacyManifestSource(privacyCurrent, requirements);
32003
32391
  const [privacyChanged, projectChanged, pushChanged] = await Promise.all([
@@ -32008,7 +32396,7 @@ ${content}
32008
32396
  return infoChanged || privacyChanged || projectChanged || pushChanged;
32009
32397
  };
32010
32398
  var configureIosPushNotifications = async (config, enabled) => {
32011
- const entitlementsPath = join22(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
32399
+ const entitlementsPath = join24(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
32012
32400
  const entitlements = await optionalSource(entitlementsPath);
32013
32401
  if (entitlements === null && !enabled)
32014
32402
  return false;
@@ -32020,7 +32408,7 @@ var configureIosPushNotifications = async (config, enabled) => {
32020
32408
  <!-- ${PUSH_END_MARKER} -->
32021
32409
  ` : "";
32022
32410
  const nextEntitlements = replacePushRegion(entitlements, entitlementRegion, entitlements.lastIndexOf("</dict>"));
32023
- const delegatePath = join22(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
32411
+ const delegatePath = join24(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
32024
32412
  const delegate = await optionalSource(delegatePath);
32025
32413
  if (delegate === null && !enabled)
32026
32414
  return false;
@@ -32069,8 +32457,8 @@ var replacePushRegion = (source, region, insertion) => {
32069
32457
  return `${source.slice(0, insertion)}${region}${source.slice(insertion)}`;
32070
32458
  };
32071
32459
  var configureAndroid2 = async (config, plan) => {
32072
- const path = join22(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
32073
- const source = await readFile19(path, "utf8");
32460
+ const path = join24(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
32461
+ const source = await readFile20(path, "utf8");
32074
32462
  const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
32075
32463
  const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
32076
32464
  `);
@@ -32105,7 +32493,7 @@ ${content}
32105
32493
  throw new TypeError(`Android google-services.json does not contain package ${config.appId}.`);
32106
32494
  const [manifestChanged, firebaseChanged] = await Promise.all([
32107
32495
  writeChangedFile2(path, nextManifest),
32108
- writeOptionalChangedFile(join22(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
32496
+ writeOptionalChangedFile(join24(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
32109
32497
  ]);
32110
32498
  return manifestChanged || firebaseChanged;
32111
32499
  };
@@ -32125,13 +32513,13 @@ init_nativeAuth();
32125
32513
  // src/mobile/nativeUpdates.ts
32126
32514
  import {
32127
32515
  mkdir as mkdir15,
32128
- readFile as readFile20,
32129
- readdir as readdir5,
32516
+ readFile as readFile21,
32517
+ readdir as readdir6,
32130
32518
  rename as rename14,
32131
32519
  rm as rm11,
32132
32520
  writeFile as writeFile18
32133
32521
  } from "fs/promises";
32134
- import { dirname as dirname15, join as join23 } from "path";
32522
+ import { dirname as dirname15, join as join25 } from "path";
32135
32523
  var START = "// absolutejs:mobile-updates:start";
32136
32524
  var END = "// absolutejs:mobile-updates:end";
32137
32525
  var PLUGIN_START = "// absolutejs:mobile-update-plugin:start";
@@ -32139,7 +32527,7 @@ var PLUGIN_END = "// absolutejs:mobile-update-plugin:end";
32139
32527
  var ANDROID_PLUGIN = "AbsoluteMobileUpdateWatchdogPlugin.java";
32140
32528
  var optionalSource2 = async (path) => {
32141
32529
  try {
32142
- return await readFile20(path, "utf8");
32530
+ return await readFile21(path, "utf8");
32143
32531
  } catch (error) {
32144
32532
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
32145
32533
  return null;
@@ -32301,9 +32689,9 @@ public final class AbsoluteMobileUpdateWatchdogPlugin: CAPPlugin, CAPBridgedPlug
32301
32689
  ${PLUGIN_END}
32302
32690
  `;
32303
32691
  var configureIos3 = async (config, enabled) => {
32304
- const path = join23(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
32305
- const capacitorConfigPath = join23(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
32306
- let source = await readFile20(path, "utf8");
32692
+ const path = join25(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
32693
+ const capacitorConfigPath = join25(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
32694
+ let source = await readFile21(path, "utf8");
32307
32695
  const launch = source.indexOf("didFinishLaunchingWithOptions");
32308
32696
  const brace = launch < 0 ? -1 : source.indexOf("{", launch);
32309
32697
  const launchRegion = enabled ? ` ${START}
@@ -32314,7 +32702,7 @@ var configureIos3 = async (config, enabled) => {
32314
32702
  `, brace) + 1, "Could not find a safe iOS location for mobile update recovery.");
32315
32703
  const plugin = enabled ? iosPluginRegion(config.updates?.bootTimeoutMs ?? 20000) : "";
32316
32704
  source = replaceMarkedRegion(source, PLUGIN_START, PLUGIN_END, plugin, source.length, "Could not find a safe iOS location for the mobile update watchdog.");
32317
- const capacitorConfigSource2 = await readFile20(capacitorConfigPath, "utf8");
32705
+ const capacitorConfigSource2 = await readFile21(capacitorConfigPath, "utf8");
32318
32706
  let capacitorConfig;
32319
32707
  try {
32320
32708
  const value = JSON.parse(capacitorConfigSource2);
@@ -32487,19 +32875,19 @@ public final class AbsoluteMobileUpdateWatchdogPlugin extends Plugin {
32487
32875
  var androidActivityInRoot = async (root) => {
32488
32876
  let entries;
32489
32877
  try {
32490
- entries = await readdir5(root, { recursive: true });
32878
+ entries = await readdir6(root, { recursive: true });
32491
32879
  } catch (error) {
32492
32880
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
32493
32881
  return;
32494
32882
  throw error;
32495
32883
  }
32496
32884
  const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
32497
- return candidate ? join23(root, candidate) : undefined;
32885
+ return candidate ? join25(root, candidate) : undefined;
32498
32886
  };
32499
32887
  var androidActivity = async (config) => {
32500
32888
  const roots = [
32501
- join23(config.nativeProjectDirectory, "android/app/src/main/java"),
32502
- join23(config.nativeProjectDirectory, "android/app/src/main/kotlin")
32889
+ join25(config.nativeProjectDirectory, "android/app/src/main/java"),
32890
+ join25(config.nativeProjectDirectory, "android/app/src/main/kotlin")
32503
32891
  ];
32504
32892
  const candidates = await Promise.all(roots.map(androidActivityInRoot));
32505
32893
  const candidate = candidates.find((value) => value !== undefined);
@@ -32598,12 +32986,12 @@ var injectAndroidActivity = (source, enabled) => {
32598
32986
  };
32599
32987
  var configureAndroid3 = async (config, enabled) => {
32600
32988
  const activityPath = await androidActivity(config);
32601
- const activity = await readFile20(activityPath, "utf8");
32989
+ const activity = await readFile21(activityPath, "utf8");
32602
32990
  const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
32603
32991
  if (!packageName)
32604
32992
  throw new TypeError("Android MainActivity package declaration was not found.");
32605
32993
  const packagePath = packageName.replaceAll(".", "/");
32606
- const pluginPath = join23(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
32994
+ const pluginPath = join25(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
32607
32995
  const changed = await Promise.all([
32608
32996
  writeChanged(activityPath, injectAndroidActivity(activity, enabled)),
32609
32997
  enabled ? writeChanged(pluginPath, androidPluginSource(packageName, config.updates?.bootTimeoutMs ?? 20000)) : removeOwnedFile(pluginPath)
@@ -32624,13 +33012,13 @@ var applyAbsoluteNativeUpdates = async (config, platforms = config.platforms) =>
32624
33012
  // src/mobile/nativeObservability.ts
32625
33013
  import {
32626
33014
  mkdir as mkdir16,
32627
- readFile as readFile21,
32628
- readdir as readdir6,
33015
+ readFile as readFile22,
33016
+ readdir as readdir7,
32629
33017
  rename as rename15,
32630
33018
  rm as rm12,
32631
33019
  writeFile as writeFile19
32632
33020
  } from "fs/promises";
32633
- import { dirname as dirname16, join as join24 } from "path";
33021
+ import { dirname as dirname16, join as join26 } from "path";
32634
33022
  var START2 = "// absolutejs:native-observability:start";
32635
33023
  var END2 = "// absolutejs:native-observability:end";
32636
33024
  var PLUGIN_START2 = "// absolutejs:native-observability-plugin:start";
@@ -32638,7 +33026,7 @@ var PLUGIN_END2 = "// absolutejs:native-observability-plugin:end";
32638
33026
  var ANDROID_PLUGIN2 = "AbsoluteMobileObservabilityPlugin.java";
32639
33027
  var optionalSource3 = async (path) => {
32640
33028
  try {
32641
- return await readFile21(path, "utf8");
33029
+ return await readFile22(path, "utf8");
32642
33030
  } catch (error) {
32643
33031
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
32644
33032
  return null;
@@ -32798,9 +33186,9 @@ public final class AbsoluteMobileObservabilityPlugin: CAPPlugin, CAPBridgedPlugi
32798
33186
  ${PLUGIN_END2}
32799
33187
  `;
32800
33188
  var configureIos4 = async (config, enabled) => {
32801
- const path = join24(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
32802
- const capacitorConfigPath = join24(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
32803
- let source = await readFile21(path, "utf8");
33189
+ const path = join26(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
33190
+ const capacitorConfigPath = join26(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
33191
+ let source = await readFile22(path, "utf8");
32804
33192
  if (enabled && !source.includes("import MetricKit")) {
32805
33193
  const capacitorImport = source.lastIndexOf("import Capacitor");
32806
33194
  if (capacitorImport < 0)
@@ -32814,7 +33202,7 @@ ${source.slice(newline + 1)}`;
32814
33202
  source = source.replace(`import MetricKit
32815
33203
  `, "");
32816
33204
  source = replaceMarkedRegion2(source, PLUGIN_START2, PLUGIN_END2, enabled ? iosPluginRegion2 : "", source.length, "Could not find a safe iOS location for native observability.");
32817
- const capacitorConfigSource2 = await readFile21(capacitorConfigPath, "utf8");
33205
+ const capacitorConfigSource2 = await readFile22(capacitorConfigPath, "utf8");
32818
33206
  let capacitorConfig;
32819
33207
  try {
32820
33208
  const value = JSON.parse(capacitorConfigSource2);
@@ -33052,19 +33440,19 @@ public final class AbsoluteMobileObservabilityPlugin extends Plugin {
33052
33440
  var androidActivityInRoot2 = async (root) => {
33053
33441
  let entries;
33054
33442
  try {
33055
- entries = await readdir6(root, { recursive: true });
33443
+ entries = await readdir7(root, { recursive: true });
33056
33444
  } catch (error) {
33057
33445
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
33058
33446
  return;
33059
33447
  throw error;
33060
33448
  }
33061
33449
  const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
33062
- return candidate ? join24(root, candidate) : undefined;
33450
+ return candidate ? join26(root, candidate) : undefined;
33063
33451
  };
33064
33452
  var androidActivity2 = async (config) => {
33065
33453
  const roots = [
33066
- join24(config.nativeProjectDirectory, "android/app/src/main/java"),
33067
- join24(config.nativeProjectDirectory, "android/app/src/main/kotlin")
33454
+ join26(config.nativeProjectDirectory, "android/app/src/main/java"),
33455
+ join26(config.nativeProjectDirectory, "android/app/src/main/kotlin")
33068
33456
  ];
33069
33457
  const candidates = await Promise.all(roots.map(androidActivityInRoot2));
33070
33458
  const candidate = candidates.find((value) => value !== undefined);
@@ -33132,11 +33520,11 @@ var injectAndroidActivity2 = (source, enabled) => {
33132
33520
  };
33133
33521
  var configureAndroid4 = async (config, enabled) => {
33134
33522
  const activityPath = await androidActivity2(config);
33135
- const activity = await readFile21(activityPath, "utf8");
33523
+ const activity = await readFile22(activityPath, "utf8");
33136
33524
  const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
33137
33525
  if (!packageName)
33138
33526
  throw new TypeError("Android MainActivity package declaration was not found.");
33139
- const pluginPath = join24(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
33527
+ const pluginPath = join26(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
33140
33528
  const changed = await Promise.all([
33141
33529
  writeChanged2(activityPath, injectAndroidActivity2(activity, enabled)),
33142
33530
  enabled ? writeChanged2(pluginPath, androidPluginSource2(packageName)) : removeOwnedFile2(pluginPath)
@@ -33161,8 +33549,8 @@ init_producerContext();
33161
33549
  init_releaseArtifact();
33162
33550
 
33163
33551
  // src/mobile/releasePublisher.ts
33164
- import { access as access14 } from "fs/promises";
33165
- import { isAbsolute as isAbsolute7, relative as relative13, resolve as resolve16, sep as sep9 } from "path";
33552
+ import { access as access15 } from "fs/promises";
33553
+ import { isAbsolute as isAbsolute7, relative as relative14, resolve as resolve16, sep as sep9 } from "path";
33166
33554
  import { pathToFileURL as pathToFileURL3 } from "url";
33167
33555
  var prepareAbsoluteIosRelease = async (publisher, options) => {
33168
33556
  if (typeof publisher.prepareIosRelease !== "function") {
@@ -33190,7 +33578,7 @@ var isPublisher = (value) => isRecord13(value) && typeof value.publish === "func
33190
33578
  var publisherModulePath = (projectRoot, requested) => {
33191
33579
  const root = resolve16(projectRoot);
33192
33580
  const path = resolve16(root, requested);
33193
- const projectRelative = relative13(root, path);
33581
+ const projectRelative = relative14(root, path);
33194
33582
  if (projectRelative === ".." || projectRelative.startsWith(`..${sep9}`) || isAbsolute7(projectRelative)) {
33195
33583
  throw new TypeError("mobile publish --registry must remain inside the project.");
33196
33584
  }
@@ -33198,7 +33586,7 @@ var publisherModulePath = (projectRoot, requested) => {
33198
33586
  };
33199
33587
  var loadAbsoluteNativeReleasePublisher = async (projectRoot, requestedModulePath) => {
33200
33588
  const modulePath = publisherModulePath(projectRoot, requestedModulePath);
33201
- await access14(modulePath).catch(() => {
33589
+ await access15(modulePath).catch(() => {
33202
33590
  throw new TypeError(`Native release registry module does not exist: ${modulePath}`);
33203
33591
  });
33204
33592
  const loaded = await import(pathToFileURL3(modulePath).href);
@@ -33262,7 +33650,7 @@ var publishAbsoluteIosRelease = async (options) => {
33262
33650
  init_pageProtocol();
33263
33651
  init_releaseArtifact();
33264
33652
  import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
33265
- import { dirname as dirname17, extname as extname6, relative as relative14, resolve as resolve17 } from "path";
33653
+ import { dirname as dirname17, extname as extname6, relative as relative15, resolve as resolve17 } from "path";
33266
33654
  import ts2 from "typescript";
33267
33655
  var ROUTE_METHODS = new Set(["get", "head"]);
33268
33656
  var SOURCE_FILTER = /\.[cm]?[jt]sx?$/;
@@ -33431,7 +33819,7 @@ var resolvePageIdentity = (expression, sourceFile, checker, projectRoot) => {
33431
33819
  const declaration = symbol?.declarations?.[0];
33432
33820
  const file = declaration?.getSourceFile().fileName ?? sourceFile.fileName;
33433
33821
  const exportedName = symbol?.name ?? expression.getText(sourceFile);
33434
- const source = posixPath(relative14(projectRoot, file));
33822
+ const source = posixPath(relative15(projectRoot, file));
33435
33823
  return `${source}#${exportedName}`;
33436
33824
  };
33437
33825
  var resolveAlias = (symbol, checker) => {
@@ -33787,7 +34175,7 @@ var inspectAbsoluteMobileRouteMetadata = (options) => {
33787
34175
  const entry = resolve17(options.entry);
33788
34176
  const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
33789
34177
  return [...analyzed.entries()].flatMap(([file, analysis]) => [...analysis.byRouteCall.values()].map(({ metadata }) => ({
33790
- file: posixPath(relative14(projectRoot, file)),
34178
+ file: posixPath(relative15(projectRoot, file)),
33791
34179
  metadata
33792
34180
  })));
33793
34181
  };
@@ -33846,11 +34234,11 @@ var resolveAbsoluteHttpUrl = (target, origin) => {
33846
34234
  var createAbsoluteHttpTransport = ({
33847
34235
  fetch: fetchImpl = globalThis.fetch,
33848
34236
  origin,
33849
- runtime
34237
+ runtime: runtime2
33850
34238
  }) => ({
33851
34239
  fetch: fetchImpl,
33852
34240
  origin: normalizeAbsoluteHttpOrigin(origin),
33853
- runtime
34241
+ runtime: runtime2
33854
34242
  });
33855
34243
  var createWebHttpTransport = (options = {}) => {
33856
34244
  const origin = options.origin ?? globalThis.location?.origin;
@@ -37784,7 +38172,7 @@ var createBeacon = (options) => {
37784
38172
  if (signals !== null && signals.mediaFailures !== false && typeof document !== "undefined") {
37785
38173
  const stallMs = signals.mediaStallMs ?? MEDIA_STALL_DEFAULT_MS;
37786
38174
  const watched = new Map;
37787
- const watch2 = (media) => {
38175
+ const watch3 = (media) => {
37788
38176
  if (watched.has(media) || !media.hasAttribute(BEACON_ATTRIBUTE.MEDIA))
37789
38177
  return;
37790
38178
  const name = media.getAttribute(BEACON_ATTRIBUTE.MEDIA)?.trim() || describeElement(media);
@@ -37845,10 +38233,10 @@ var createBeacon = (options) => {
37845
38233
  };
37846
38234
  const scan = (root) => {
37847
38235
  if (root instanceof HTMLMediaElement)
37848
- watch2(root);
38236
+ watch3(root);
37849
38237
  for (const media of Array.from(root.querySelectorAll?.(`audio[${BEACON_ATTRIBUTE.MEDIA}], video[${BEACON_ATTRIBUTE.MEDIA}]`) ?? [])) {
37850
38238
  if (media instanceof HTMLMediaElement)
37851
- watch2(media);
38239
+ watch3(media);
37852
38240
  }
37853
38241
  };
37854
38242
  scan(document);
@@ -37898,7 +38286,7 @@ var createBeacon = (options) => {
37898
38286
  const originalOpen = factory.open.bind(factory);
37899
38287
  const originalDeleteDatabase = factory.deleteDatabase.bind(factory);
37900
38288
  const reported = new WeakSet;
37901
- const watch2 = (request, operation2, database) => {
38289
+ const watch3 = (request, operation2, database) => {
37902
38290
  request.addEventListener("error", () => {
37903
38291
  if (reported.has(request))
37904
38292
  return;
@@ -37914,8 +38302,8 @@ var createBeacon = (options) => {
37914
38302
  }, { once: true });
37915
38303
  return request;
37916
38304
  };
37917
- const wrappedOpen = (name, version) => watch2(version === undefined ? originalOpen(name) : originalOpen(name, version), "open", name);
37918
- const wrappedDeleteDatabase = (name) => watch2(originalDeleteDatabase(name), "delete", name);
38305
+ const wrappedOpen = (name, version) => watch3(version === undefined ? originalOpen(name) : originalOpen(name, version), "open", name);
38306
+ const wrappedDeleteDatabase = (name) => watch3(originalDeleteDatabase(name), "delete", name);
37919
38307
  try {
37920
38308
  factory.open = wrappedOpen;
37921
38309
  factory.deleteDatabase = wrappedDeleteDatabase;
@@ -39979,44 +40367,44 @@ var createAbsoluteMobileUpdateClient = (options) => {
39979
40367
  };
39980
40368
  };
39981
40369
  // src/mobile/updatePublisher.ts
39982
- import { access as access15 } from "fs/promises";
39983
- import { isAbsolute as isAbsolute8, relative as relative16, resolve as resolve19, sep as sep10 } from "path";
40370
+ import { access as access16 } from "fs/promises";
40371
+ import { isAbsolute as isAbsolute8, relative as relative17, resolve as resolve19, sep as sep10 } from "path";
39984
40372
  import { pathToFileURL as pathToFileURL4 } from "url";
39985
40373
 
39986
40374
  // src/mobile/updateSigning.ts
39987
- import { createHash as createHash13, sign, verify } from "crypto";
40375
+ import { createHash as createHash14, sign, verify } from "crypto";
39988
40376
  import {
39989
40377
  cp as cp3,
39990
40378
  mkdir as mkdir17,
39991
40379
  mkdtemp as mkdtemp8,
39992
- readdir as readdir7,
39993
- readFile as readFile22,
40380
+ readdir as readdir8,
40381
+ readFile as readFile23,
39994
40382
  rename as rename16,
39995
40383
  rm as rm13,
39996
40384
  stat as stat4,
39997
40385
  writeFile as writeFile20
39998
40386
  } from "fs/promises";
39999
- import { dirname as dirname18, join as join25, relative as relative15, resolve as resolve18 } from "path";
40387
+ import { dirname as dirname18, join as join27, relative as relative16, resolve as resolve18 } from "path";
40000
40388
  var UPDATE_MANIFEST_FILE = "update.json";
40001
40389
  var UPDATE_FILES_DIRECTORY = "files";
40002
- var sha2562 = (value) => createHash13("sha256").update(value).digest("hex");
40390
+ var sha2562 = (value) => createHash14("sha256").update(value).digest("hex");
40003
40391
  var listFiles = async (root, directory = root) => {
40004
- const entries = await readdir7(directory, { withFileTypes: true });
40392
+ const entries = await readdir8(directory, { withFileTypes: true });
40005
40393
  const paths = await Promise.all(entries.map(async (entry) => {
40006
- const path = join25(directory, entry.name);
40394
+ const path = join27(directory, entry.name);
40007
40395
  if (entry.isDirectory())
40008
40396
  return listFiles(root, path);
40009
40397
  if (!entry.isFile())
40010
40398
  throw new TypeError("Mobile updates cannot contain links or special files.");
40011
- return [relative15(root, path).replaceAll("\\", "/")];
40399
+ return [relative16(root, path).replaceAll("\\", "/")];
40012
40400
  }));
40013
40401
  return paths.flat().sort((left, right) => left.localeCompare(right));
40014
40402
  };
40015
40403
  var inspectFiles = async (root, paths) => Promise.all(paths.map(async (path) => {
40016
- const source = join25(root, path);
40404
+ const source = join27(root, path);
40017
40405
  const [metadata, contents] = await Promise.all([
40018
40406
  stat4(source),
40019
- readFile22(source)
40407
+ readFile23(source)
40020
40408
  ]);
40021
40409
  return { bytes: metadata.size, path, sha256: sha2562(contents) };
40022
40410
  }));
@@ -40052,14 +40440,14 @@ var buildAbsoluteMobileUpdate = async (options) => {
40052
40440
  }
40053
40441
  });
40054
40442
  await mkdir17(outputRoot, { recursive: true });
40055
- const outputDirectory = join25(outputRoot, manifest.releaseId);
40056
- const staging = await mkdtemp8(join25(outputRoot, ".stage-"));
40443
+ const outputDirectory = join27(outputRoot, manifest.releaseId);
40444
+ const staging = await mkdtemp8(join27(outputRoot, ".stage-"));
40057
40445
  try {
40058
- await cp3(bundleDirectory, join25(staging, UPDATE_FILES_DIRECTORY), {
40446
+ await cp3(bundleDirectory, join27(staging, UPDATE_FILES_DIRECTORY), {
40059
40447
  force: true,
40060
40448
  recursive: true
40061
40449
  });
40062
- await writeFile20(join25(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
40450
+ await writeFile20(join27(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
40063
40451
  `);
40064
40452
  await rename16(staging, outputDirectory);
40065
40453
  } catch (error) {
@@ -40070,7 +40458,7 @@ var buildAbsoluteMobileUpdate = async (options) => {
40070
40458
  }
40071
40459
  return {
40072
40460
  manifest,
40073
- manifestPath: join25(outputDirectory, UPDATE_MANIFEST_FILE),
40461
+ manifestPath: join27(outputDirectory, UPDATE_MANIFEST_FILE),
40074
40462
  outputDirectory
40075
40463
  };
40076
40464
  };
@@ -40082,7 +40470,7 @@ var copyAbsoluteMobileUpdateFile = async (updateDirectory, path, destination) =>
40082
40470
  await mkdir17(dirname18(destination), { recursive: true });
40083
40471
  await cp3(source, destination, { force: true });
40084
40472
  };
40085
- var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile22(join25(resolve18(directory), UPDATE_MANIFEST_FILE), "utf8")));
40473
+ var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile23(join27(resolve18(directory), UPDATE_MANIFEST_FILE), "utf8")));
40086
40474
  var verifyAbsoluteMobileUpdateSignature = (manifestValue, publicKey) => {
40087
40475
  const manifest = parseAbsoluteMobileUpdateManifest(manifestValue);
40088
40476
  const valid = verify("sha256", absoluteMobileUpdateSigningPayload(unsignedAbsoluteMobileUpdate(manifest)), { dsaEncoding: "ieee-p1363", key: publicKey }, Buffer.from(manifest.signature.value, "base64"));
@@ -40201,14 +40589,14 @@ var isPublisher2 = (value) => object5(value) && typeof value.publishUpdate === "
40201
40589
  var projectPath2 = (projectRoot, requested, label) => {
40202
40590
  const root = resolve19(projectRoot);
40203
40591
  const path = resolve19(root, requested);
40204
- const projectRelative = relative16(root, path);
40592
+ const projectRelative = relative17(root, path);
40205
40593
  if (projectRelative === ".." || projectRelative.startsWith(`..${sep10}`) || isAbsolute8(projectRelative))
40206
40594
  throw new TypeError(`${label} must remain inside the project.`);
40207
40595
  return path;
40208
40596
  };
40209
40597
  var loadAbsoluteMobileUpdatePublisher = async (projectRoot, requestedModulePath) => {
40210
40598
  const modulePath = projectPath2(projectRoot, requestedModulePath, "mobile update registry");
40211
- await access15(modulePath).catch(() => {
40599
+ await access16(modulePath).catch(() => {
40212
40600
  throw new TypeError(`Mobile update registry does not exist: ${modulePath}`);
40213
40601
  });
40214
40602
  const loaded = await import(pathToFileURL4(modulePath).href);
@@ -40259,7 +40647,7 @@ var rollbackAbsoluteMobileUpdate = async (options) => {
40259
40647
  return result;
40260
40648
  };
40261
40649
  // src/mobile/updateRollout.ts
40262
- import { createHash as createHash14 } from "crypto";
40650
+ import { createHash as createHash15 } from "crypto";
40263
40651
  var UUID_PATTERN = /^[a-f0-9]{8}-[a-f0-9]{4}-[1-8][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u;
40264
40652
  var requireHeader = (headers, name) => {
40265
40653
  const value = headers.get(name);
@@ -40274,7 +40662,7 @@ var isAbsoluteMobileUpdateRolloutMember = (options) => {
40274
40662
  return false;
40275
40663
  if (options.rollout === 1)
40276
40664
  return true;
40277
- const digest = createHash14("sha256").update(`${options.appId}\x00${options.channel}\x00${options.releaseId}\x00${options.installationId}`).digest();
40665
+ const digest = createHash15("sha256").update(`${options.appId}\x00${options.channel}\x00${options.releaseId}\x00${options.installationId}`).digest();
40278
40666
  const bucket = digest.readUInt32BE(0) / 4294967296;
40279
40667
  return bucket < options.rollout;
40280
40668
  };
@@ -40381,6 +40769,7 @@ export {
40381
40769
  copyAbsoluteMobileUpdateFile,
40382
40770
  createAbsoluteExpoBridgeError,
40383
40771
  createAbsoluteExpoBridgeResponse,
40772
+ createAbsoluteExpoNativeWatcher,
40384
40773
  createAbsoluteIosNativeWatcher,
40385
40774
  createAbsoluteMobileAssociationDocuments,
40386
40775
  createAbsoluteMobileAssociationPlugin,
@@ -40412,6 +40801,7 @@ export {
40412
40801
  finalizeAbsoluteMobileCompatibilityBuild,
40413
40802
  finalizeAbsoluteMobilePage,
40414
40803
  finalizeAbsoluteRouteData,
40804
+ fingerprintAbsoluteExpoNativeInputs,
40415
40805
  fingerprintAbsoluteIosDevProject,
40416
40806
  fingerprintAbsoluteIosNativeProject,
40417
40807
  fingerprintAbsoluteMobileUpdateRuntime,
@@ -40440,6 +40830,7 @@ export {
40440
40830
  installAbsoluteMobileSyncRemediation,
40441
40831
  installAbsoluteMobileUiPrimitives,
40442
40832
  installAbsoluteRemoteMacAgent,
40833
+ isAbsoluteExpoNativeRootInput,
40443
40834
  isAbsoluteIosNativeRootInput,
40444
40835
  isAbsoluteMobileUpdateRolloutMember,
40445
40836
  listAbsoluteRemoteMacProfiles,
@@ -40540,5 +40931,5 @@ export {
40540
40931
  writeAbsoluteMobileUpdateRegistry
40541
40932
  };
40542
40933
 
40543
- //# debugId=8F55062CC1F78A5264756E2164756E21
40934
+ //# debugId=60D5DDBF8A7817D064756E2164756E21
40544
40935
  //# sourceMappingURL=index.js.map