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

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 (38) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/changelog.json +41 -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-5hchbcbd.js → compile-wkfd88w7.js} +5 -5
  9. package/dist/cli/{dev-aykeaa7b.js → dev-01zcxngn.js} +83 -11
  10. package/dist/cli/{expoDevController-tr63cg78.js → expoDevController-k15hftqn.js} +25 -1
  11. package/dist/cli/expoNativeWatcher-rmc95bak.js +138 -0
  12. package/dist/cli/{expoProject-dac8fqhq.js → expoProject-mmm3s62b.js} +1 -1
  13. package/dist/cli/{index-fn44wefq.js → index-3sdvzrv2.js} +37 -28
  14. package/dist/cli/index-bw4ktfnz.js +11 -0
  15. package/dist/cli/{index-jqdt7841.js → index-kh44yx23.js} +1 -1
  16. package/dist/cli/{index-39j0dhq7.js → index-v5knwk7v.js} +1 -1
  17. package/dist/cli/{index-tame6e2c.js → index-wqhbxtyp.js} +49 -12
  18. package/dist/cli/index.js +5 -5
  19. package/dist/cli/{mobile-bg1jy34n.js → mobile-pbe1a667.js} +20 -12
  20. package/dist/cli/{remoteMacProtocol-vw931n0a.js → remoteMacProtocol-kqvkp0qd.js} +2 -1
  21. package/dist/cli/{start-7jg0csqy.js → start-dw5crgp7.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 +371 -162
  27. package/dist/mobile/index.js.map +10 -8
  28. package/dist/mobile/mobilePreviewClient.ts +1 -1
  29. package/dist/mobile/remoteMacAgentEntry.js +105 -68
  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/expoDevController.d.ts +2 -6
  33. package/dist/src/mobile/expoNativeObservability.d.ts +1 -1
  34. package/dist/src/mobile/expoNativeWatcher.d.ts +21 -0
  35. package/dist/src/mobile/index.d.ts +1 -0
  36. package/dist/src/mobile/remoteMacProtocol.d.ts +1 -4
  37. package/dist/src/utils/unrefTimer.d.ts +5 -0
  38. 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 join20 } 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 = join20(homedir3(), ".absolutejs");
19368
+ configPath = join20(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 join21, 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 = join21(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) => {
@@ -27843,6 +27858,27 @@ public final class AbsoluteMobileObservabilityModule: Module, MXMetricManagerSub
27843
27858
  }
27844
27859
  }
27845
27860
  }
27861
+
27862
+ #if DEBUG
27863
+ AsyncFunction("enqueueForTesting") { (options: [String: String]) -> Bool in
27864
+ guard let testId = options["testId"],
27865
+ testId.range(of: "^[A-Za-z0-9._:-]{1,128}$", options: .regularExpression) != nil else { return false }
27866
+ let key = "absolute-native-observability-test-id"
27867
+ guard UserDefaults.standard.string(forKey: key) != testId else { return false }
27868
+ UserDefaults.standard.set(testId, forKey: key)
27869
+ Self.queue.sync {
27870
+ Self.enqueue(
27871
+ kind: "crash",
27872
+ occurredAt: Date().timeIntervalSince1970 * 1000,
27873
+ details: [
27874
+ "message": "token=mobile-observability-secret",
27875
+ "source": "absolutejs-conformance"
27876
+ ]
27877
+ )
27878
+ }
27879
+ return true
27880
+ }
27881
+ #endif
27846
27882
  }
27847
27883
 
27848
27884
  private static func root() -> URL? {
@@ -28126,6 +28162,7 @@ import { ABSOLUTE_MOBILE_MANIFEST } from './webAssets';
28126
28162
  type NativeObservabilityModule = {
28127
28163
  acknowledge(options: { ids: string[] }): Promise<void>;
28128
28164
  crashForTesting(options: { testId: string }): Promise<boolean>;
28165
+ enqueueForTesting(options: { testId: string }): Promise<boolean>;
28129
28166
  pending(): Promise<{ reports: unknown[] }>;
28130
28167
  };
28131
28168
  type NativeReport = { details: Record<string, unknown>; id: string; kind: string; occurredAt: number; platform: 'android' | 'ios' };
@@ -28187,6 +28224,12 @@ export const startAbsoluteExpoNativeObservability = () => {
28187
28224
  return drain();
28188
28225
  };
28189
28226
  export const crashAbsoluteExpoNativeObservabilityForTesting = (testId: string) => native.crashForTesting({ testId });
28227
+ export const enqueueAbsoluteExpoNativeObservabilityForTesting = async (testId: string) => {
28228
+ await drain();
28229
+ const enqueued = await native.enqueueForTesting({ testId });
28230
+ await drain();
28231
+ return enqueued;
28232
+ };
28190
28233
  `;
28191
28234
  var absoluteExpoNativeObservabilityFiles = (project) => new Map([
28192
28235
  [
@@ -28310,7 +28353,7 @@ var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map
28310
28353
  var expoPackage = (auth, sync, devices, updates) => ({
28311
28354
  dependencies: {
28312
28355
  "@absolutejs/devices": "0.7.0",
28313
- "@absolutejs/devices-expo": "0.0.2",
28356
+ "@absolutejs/devices-expo": "0.0.3",
28314
28357
  ...auth ? {
28315
28358
  "@absolutejs/auth": ABSOLUTE_EXPO_AUTH_CORE_VERSION,
28316
28359
  [ABSOLUTE_EXPO_AUTH_PACKAGE]: ABSOLUTE_EXPO_AUTH_VERSION
@@ -28917,7 +28960,7 @@ var webHostSource = (config, auth, sync) => {
28917
28960
  const nativeRoutePatterns = nativeRoutes.map((route) => route.split("/").filter(Boolean));
28918
28961
  return `${EXPO_GENERATED_HEADER}import * as Linking from 'expo-linking';
28919
28962
  import { router, usePathname } from 'expo-router';
28920
- import { useEffect, useRef, useState } from 'react';
28963
+ import { useEffect, useMemo, useRef, useState } from 'react';
28921
28964
  import { ActivityIndicator, BackHandler, Platform, StyleSheet, View } from 'react-native';
28922
28965
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
28923
28966
  import { WebView, type WebViewMessageEvent } from 'react-native-webview';
@@ -29072,17 +29115,21 @@ const authStatus = async () => {
29072
29115
  return { principal: principal ? { namespace: principal.namespace } : null, user };` : "throw new Error('Expo Auth is not configured.');"}
29073
29116
  };
29074
29117
 
29075
- export function AbsoluteWebHost() {
29076
- const pathname = usePathname() || '/';
29118
+ export type AbsoluteWebHostProps = { path?: string };
29119
+
29120
+ export function AbsoluteWebHost({ path }: AbsoluteWebHostProps = {}) {
29121
+ const routerPathname = usePathname() || '/';
29122
+ const pathname = path?.startsWith('/') && !path.startsWith('//') ? path : routerPathname;
29077
29123
  const safeAreaInsets = useSafeAreaInsets();
29078
29124
  const webView = useRef<WebView>(null);
29079
29125
  const devicesBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
29080
29126
  const syncBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
29081
29127
  const [indexUri, setIndexUri] = useState<string>();
29082
- const [canGoBack, setCanGoBack] = useState(false);
29128
+ const canGoBack = useRef(false);
29083
29129
  const [runtimeReady, setRuntimeReady] = useState(!AUTH_ENABLED && !SYNC_ENABLED);
29084
29130
  const [devicesReady, setDevicesReady] = useState(false);
29085
29131
  const activeWebPath = useRef(pathname);
29132
+ const webSource = useMemo(() => indexUri ? { uri: indexUri } : undefined, [indexUri]);
29086
29133
 
29087
29134
  useEffect(() => {
29088
29135
  if (!AUTH_ENABLED && !SYNC_ENABLED) return;
@@ -29140,7 +29187,7 @@ export function AbsoluteWebHost() {
29140
29187
  if (!active) return;
29141
29188
  respond({ event, format: BRIDGE_FORMAT, kind: 'event', path: activeWebPath.current, payload });
29142
29189
  }).then(host => {
29143
- if (!active) return void host.close();
29190
+ if (!active) return void Promise.resolve(host.close()).catch(() => undefined);
29144
29191
  devicesBridge.current = host;
29145
29192
  setDevicesReady(true);
29146
29193
  });
@@ -29148,7 +29195,7 @@ export function AbsoluteWebHost() {
29148
29195
  active = false;
29149
29196
  const host = devicesBridge.current;
29150
29197
  devicesBridge.current = undefined;
29151
- void host?.close();
29198
+ if (host) void Promise.resolve(host.close()).catch(() => undefined);
29152
29199
  };
29153
29200
  }, []);
29154
29201
  const hasOrigin = (source: string, origin: string) => {
@@ -29168,7 +29215,7 @@ export function AbsoluteWebHost() {
29168
29215
  return;
29169
29216
  }
29170
29217
  if (message.kind === 'event' && message.event === 'back-unhandled') {
29171
- if (canGoBack) webView.current?.goBack();
29218
+ if (canGoBack.current) webView.current?.goBack();
29172
29219
  else BackHandler.exitApp();
29173
29220
  return;
29174
29221
  }
@@ -29202,22 +29249,27 @@ export function AbsoluteWebHost() {
29202
29249
  }
29203
29250
  };
29204
29251
 
29205
- if (!indexUri || !runtimeReady || !devicesReady) return <View style={styles.loading}><ActivityIndicator /></View>;
29252
+ if (!webSource || !runtimeReady || !devicesReady) return <View style={styles.loading}><ActivityIndicator /></View>;
29206
29253
  return <WebView
29207
29254
  allowFileAccess
29208
29255
  allowFileAccessFromFileURLs
29209
29256
  allowUniversalAccessFromFileURLs={false}
29210
- allowingReadAccessToURL={indexUri.slice(0, indexUri.lastIndexOf('/') + 1)}
29257
+ allowingReadAccessToURL={webSource.uri.slice(0, webSource.uri.lastIndexOf('/') + 1)}
29211
29258
  injectedJavaScriptBeforeContentLoaded={bridgeBootstrap(pathname, safeAreaInsets)}
29212
29259
  onMessage={onMessage}
29213
- onNavigationStateChange={state => setCanGoBack(state.canGoBack)}
29260
+ onNavigationStateChange={state => {
29261
+ canGoBack.current = state.canGoBack;
29262
+ if (!DEV_ORIGIN || !hasOrigin(state.url, DEV_ORIGIN)) return;
29263
+ const route = new URL(state.url);
29264
+ activeWebPath.current = route.pathname + route.search + route.hash;
29265
+ }}
29214
29266
  onShouldStartLoadWithRequest={request => {
29215
29267
  if (request.url.startsWith('file:') || hasOrigin(request.url, PRODUCTION_ORIGIN) || DEV_ORIGIN && hasOrigin(request.url, DEV_ORIGIN)) return true;
29216
29268
  void Linking.openURL(request.url);
29217
29269
  return false;
29218
29270
  }}
29219
29271
  ref={webView}
29220
- source={{ uri: indexUri }}
29272
+ source={webSource}
29221
29273
  style={styles.web}
29222
29274
  />;
29223
29275
  }
@@ -30964,18 +31016,42 @@ var startAbsoluteExpoDevSession = async (options) => {
30964
31016
  publishTiming("starting-metro", performance.now() - metroStarted);
30965
31017
  await runNativeCommands(nativeCommands);
30966
31018
  setState("ready");
30967
- return {
31019
+ let closed = false;
31020
+ let rebuildQueue = Promise.resolve();
31021
+ const session = {
30968
31022
  metroPort: plan.metroPort,
30969
31023
  platforms: options.platforms,
30970
31024
  timings,
30971
31025
  close: async () => {
31026
+ if (closed)
31027
+ return;
31028
+ closed = true;
30972
31029
  options.signal?.removeEventListener("abort", abort);
31030
+ await rebuildQueue;
30973
31031
  if (metro)
30974
31032
  await stopProcess(metro);
30975
31033
  await closeEnrollmentServer();
30976
31034
  setState("closed");
31035
+ },
31036
+ rebuild: () => {
31037
+ const rebuild = rebuildQueue.then(async () => {
31038
+ if (closed)
31039
+ throw new Error("The Expo development session is closed.");
31040
+ if (prepareCommand)
31041
+ await runPrepareCommand(prepareCommand);
31042
+ await runNativeCommands(nativeCommands);
31043
+ setState("ready");
31044
+ return session;
31045
+ });
31046
+ rebuildQueue = rebuild.then(() => {
31047
+ return;
31048
+ }, () => {
31049
+ return;
31050
+ });
31051
+ return rebuild;
30977
31052
  }
30978
31053
  };
31054
+ return session;
30979
31055
  } catch (error) {
30980
31056
  options.signal?.removeEventListener("abort", abort);
30981
31057
  if (metro)
@@ -30985,9 +31061,139 @@ var startAbsoluteExpoDevSession = async (options) => {
30985
31061
  throw error;
30986
31062
  }
30987
31063
  };
31064
+ // src/mobile/expoNativeWatcher.ts
31065
+ import { watch as watch2 } from "fs";
31066
+ import { access as access12, readdir as readdir5, readFile as readFile16 } from "fs/promises";
31067
+ import { basename as basename5, join as join18, relative as relative12 } from "path";
31068
+ import { createHash as createHash13 } from "crypto";
31069
+ var NATIVE_CHANGE_DEBOUNCE_MS2 = 500;
31070
+ var ROOT_NATIVE_INPUTS2 = new Set([
31071
+ "absolute.config.js",
31072
+ "absolute.config.mjs",
31073
+ "absolute.config.ts",
31074
+ "absolutejs.config.js",
31075
+ "absolutejs.config.mjs",
31076
+ "absolutejs.config.ts",
31077
+ "bun.lock",
31078
+ "bun.lockb",
31079
+ "package.json"
31080
+ ]);
31081
+ var EXPO_NATIVE_DIRECTORIES = ["modules", "plugins"];
31082
+ var exists5 = async (path) => access12(path).then(() => true, () => false);
31083
+ var filesIn = async (directory, prefix) => {
31084
+ if (!await exists5(directory))
31085
+ return [];
31086
+ const entries = await readdir5(directory, { withFileTypes: true });
31087
+ const nested = await Promise.all(entries.map((entry) => {
31088
+ const path = join18(directory, entry.name);
31089
+ const name = `${prefix}/${entry.name}`;
31090
+ if (entry.isDirectory())
31091
+ return filesIn(path, name);
31092
+ return Promise.resolve(entry.isFile() ? [{ name, path }] : []);
31093
+ }));
31094
+ return nested.flat().sort((left, right) => left.name.localeCompare(right.name));
31095
+ };
31096
+ var fingerprintAbsoluteExpoNativeInputs = async (options) => {
31097
+ const hash = createHash13("sha256");
31098
+ const rootFiles = await Promise.all([...ROOT_NATIVE_INPUTS2].sort().map(async (name) => {
31099
+ const path = join18(options.projectRoot, name);
31100
+ return await exists5(path) ? [{ name: `root/${name}`, path }] : [];
31101
+ }));
31102
+ const nativeFiles = await Promise.all(EXPO_NATIVE_DIRECTORIES.map((name) => filesIn(join18(options.expoProjectDirectory, name), name)));
31103
+ const files = [...rootFiles.flat(), ...nativeFiles.flat()].sort((left, right) => left.name.localeCompare(right.name));
31104
+ const contents = await Promise.all(files.map(({ path }) => readFile16(path)));
31105
+ files.forEach(({ name }, index) => {
31106
+ hash.update(name);
31107
+ hash.update(contents[index] ?? Buffer.alloc(0));
31108
+ });
31109
+ return hash.digest("hex");
31110
+ };
31111
+ var isAbsoluteExpoNativeRootInput = (path) => ROOT_NATIVE_INPUTS2.has(basename5(path));
31112
+ var createAbsoluteExpoNativeWatcher = async (options) => {
31113
+ let fingerprint = await fingerprintAbsoluteExpoNativeInputs(options);
31114
+ let closed = false;
31115
+ let running = false;
31116
+ let timer;
31117
+ let rootInputChanged = false;
31118
+ const changedPaths = new Set;
31119
+ const watchers = [];
31120
+ const debounceMs = options.debounceMs ?? NATIVE_CHANGE_DEBOUNCE_MS2;
31121
+ const close = () => {
31122
+ if (closed)
31123
+ return;
31124
+ closed = true;
31125
+ if (timer)
31126
+ clearTimeout(timer);
31127
+ watchers.forEach((watcher) => watcher.close());
31128
+ options.signal?.removeEventListener("abort", close);
31129
+ };
31130
+ const schedule = () => {
31131
+ if (closed || running)
31132
+ return;
31133
+ if (timer)
31134
+ clearTimeout(timer);
31135
+ timer = setTimeout(() => void flush(), debounceMs);
31136
+ };
31137
+ const record = (path, root) => {
31138
+ if (closed)
31139
+ return;
31140
+ changedPaths.add(path);
31141
+ rootInputChanged ||= root;
31142
+ schedule();
31143
+ };
31144
+ const flush = async () => {
31145
+ timer = undefined;
31146
+ if (closed || running || changedPaths.size === 0)
31147
+ return;
31148
+ running = true;
31149
+ const paths = [...changedPaths].sort();
31150
+ const rootChanged = rootInputChanged;
31151
+ changedPaths.clear();
31152
+ rootInputChanged = false;
31153
+ try {
31154
+ const next = await fingerprintAbsoluteExpoNativeInputs(options);
31155
+ if (next === fingerprint)
31156
+ return;
31157
+ await options.onChange({
31158
+ afterFingerprint: next,
31159
+ beforeFingerprint: fingerprint,
31160
+ paths,
31161
+ rootInputChanged: rootChanged
31162
+ });
31163
+ fingerprint = await fingerprintAbsoluteExpoNativeInputs(options);
31164
+ } catch (error) {
31165
+ options.onError?.(error);
31166
+ } finally {
31167
+ running = false;
31168
+ if (changedPaths.size > 0)
31169
+ schedule();
31170
+ }
31171
+ };
31172
+ const nativeDirectories = (await Promise.all(EXPO_NATIVE_DIRECTORIES.map(async (name) => {
31173
+ const directory = join18(options.expoProjectDirectory, name);
31174
+ return await exists5(directory) ? [directory] : [];
31175
+ }))).flat();
31176
+ nativeDirectories.forEach((directory) => {
31177
+ watchers.push(watch2(directory, { recursive: true }, (_event, filename) => {
31178
+ if (!filename)
31179
+ return;
31180
+ record(relative12(options.expoProjectDirectory, join18(directory, String(filename))), false);
31181
+ }));
31182
+ });
31183
+ watchers.push(watch2(options.projectRoot, (_event, filename) => {
31184
+ if (!filename)
31185
+ return;
31186
+ const path = String(filename);
31187
+ if (isAbsoluteExpoNativeRootInput(path))
31188
+ record(path, true);
31189
+ }));
31190
+ watchers.forEach((watcher) => watcher.on("error", (error) => options.onError?.(error)));
31191
+ options.signal?.addEventListener("abort", close, { once: true });
31192
+ return { close };
31193
+ };
30988
31194
  // src/mobile/expoUpdate.ts
30989
- import { access as access12, mkdir as mkdir13, readFile as readFile16, writeFile as writeFile14 } from "fs/promises";
30990
- import { dirname as dirname12, extname as extname4, join as join18 } from "path";
31195
+ import { access as access13, mkdir as mkdir13, readFile as readFile17, writeFile as writeFile14 } from "fs/promises";
31196
+ import { dirname as dirname12, extname as extname4, join as join19 } from "path";
30991
31197
  var ABSOLUTE_EXPO_UPDATE_DESCRIPTOR = "_absolute/expo-update.json";
30992
31198
  var ABSOLUTE_EXPO_UPDATE_FORMAT = 1;
30993
31199
  var object4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -31053,7 +31259,7 @@ var parseAbsoluteExpoUpdateDescriptor = (value) => {
31053
31259
  };
31054
31260
  };
31055
31261
  var finalizeAbsoluteExpoUpdateExport = async (options) => {
31056
- const metadata = JSON.parse(await readFile16(join18(options.exportDirectory, "metadata.json"), "utf8"));
31262
+ const metadata = JSON.parse(await readFile17(join19(options.exportDirectory, "metadata.json"), "utf8"));
31057
31263
  if (!object4(metadata) || !object4(metadata.fileMetadata))
31058
31264
  throw new TypeError("Expo export metadata.json is invalid.");
31059
31265
  const descriptor = parseAbsoluteExpoUpdateDescriptor({
@@ -31064,10 +31270,10 @@ var finalizeAbsoluteExpoUpdateExport = async (options) => {
31064
31270
  runtimeVersion: options.runtimeVersion
31065
31271
  });
31066
31272
  const referenced = Object.values(descriptor.platforms).flatMap((entry) => entry ? [entry.launchAsset, ...entry.assets] : []);
31067
- await Promise.all(referenced.map(({ path }) => access12(join18(options.exportDirectory, path)).catch(() => {
31273
+ await Promise.all(referenced.map(({ path }) => access13(join19(options.exportDirectory, path)).catch(() => {
31068
31274
  throw new TypeError(`Expo export metadata references missing asset ${path}.`);
31069
31275
  })));
31070
- const destination = join18(options.exportDirectory, ABSOLUTE_EXPO_UPDATE_DESCRIPTOR);
31276
+ const destination = join19(options.exportDirectory, ABSOLUTE_EXPO_UPDATE_DESCRIPTOR);
31071
31277
  await mkdir13(dirname12(destination), { recursive: true });
31072
31278
  await writeFile14(destination, `${JSON.stringify(descriptor, null, "\t")}
31073
31279
  `);
@@ -31079,8 +31285,8 @@ init_config();
31079
31285
 
31080
31286
  // src/mobile/ciWorkflow.ts
31081
31287
  import { existsSync as existsSync4 } from "fs";
31082
- import { access as access13, mkdir as mkdir14, readFile as readFile17, writeFile as writeFile15 } from "fs/promises";
31083
- import { dirname as dirname13, extname as extname5, relative as relative12, resolve as resolve15, sep as sep8 } from "path";
31288
+ import { access as access14, mkdir as mkdir14, readFile as readFile18, writeFile as writeFile15 } from "fs/promises";
31289
+ import { dirname as dirname13, extname as extname5, relative as relative13, resolve as resolve15, sep as sep8 } from "path";
31084
31290
  var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1;
31085
31291
  var SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
31086
31292
  var CI_ENV_INDENTATION = 6;
@@ -31099,9 +31305,9 @@ var RESERVED_SECRET_NAMES = new Set([
31099
31305
  "APP_STORE_CONNECT_KEY_ID",
31100
31306
  "APP_STORE_CONNECT_PRIVATE_KEY_BASE64"
31101
31307
  ]);
31102
- var exists5 = async (path) => {
31308
+ var exists6 = async (path) => {
31103
31309
  try {
31104
- await access13(path);
31310
+ await access14(path);
31105
31311
  return true;
31106
31312
  } catch {
31107
31313
  return false;
@@ -31111,7 +31317,7 @@ var yamlString = (value) => `'${value.replaceAll("'", "''")}'`;
31111
31317
  var projectPath = (projectRoot, value, field2, options = {}) => {
31112
31318
  const root = resolve15(projectRoot);
31113
31319
  const path = resolve15(root, value);
31114
- const portable = relative12(root, path).replaceAll("\\", "/");
31320
+ const portable = relative13(root, path).replaceAll("\\", "/");
31115
31321
  if (portable === ".." || portable.startsWith(`..${sep8}`) || portable.startsWith("../") || portable === "") {
31116
31322
  throw new TypeError(`${field2} must remain inside the project root.`);
31117
31323
  }
@@ -31125,7 +31331,7 @@ var workflowOutputPath = (projectRoot, value) => {
31125
31331
  const root = resolve15(projectRoot);
31126
31332
  const workflows = resolve15(root, ".github/workflows");
31127
31333
  const path = resolve15(root, value ?? ".github/workflows/absolute-mobile.yml");
31128
- const portable = relative12(workflows, path);
31334
+ const portable = relative13(workflows, path);
31129
31335
  if (portable === ".." || portable.startsWith(`..${sep8}`) || extname5(path) !== ".yml" && extname5(path) !== ".yaml") {
31130
31336
  throw new TypeError("mobile ci github --output must be a .yml or .yaml file inside .github/workflows.");
31131
31337
  }
@@ -31555,9 +31761,9 @@ ${bundleAuditSteps}${platforms.includes("android") ? androidJob({ customSecrets,
31555
31761
  var writeAbsoluteMobileGithubWorkflow = async (options) => {
31556
31762
  const path = workflowOutputPath(options.projectRoot, options.outputPath);
31557
31763
  const generated = createAbsoluteMobileGithubWorkflow(options);
31558
- const previous = await exists5(path) ? await readFile17(path, "utf8") : undefined;
31764
+ const previous = await exists6(path) ? await readFile18(path, "utf8") : undefined;
31559
31765
  if (previous !== undefined && previous !== generated.workflow && !options.force)
31560
- throw new TypeError(`${relative12(options.projectRoot, path)} already exists and differs. Rerun with --force to replace the generated workflow.`);
31766
+ throw new TypeError(`${relative13(options.projectRoot, path)} already exists and differs. Rerun with --force to replace the generated workflow.`);
31561
31767
  if (previous !== generated.workflow) {
31562
31768
  await mkdir14(dirname13(path), { recursive: true });
31563
31769
  await writeFile15(path, generated.workflow);
@@ -31578,15 +31784,15 @@ init_materializedBundle();
31578
31784
  init_mobilePreview();
31579
31785
 
31580
31786
  // src/mobile/nativeDeepLinks.ts
31581
- import { readFile as readFile18, rename as rename12, writeFile as writeFile16 } from "fs/promises";
31582
- import { join as join21 } from "path";
31787
+ import { readFile as readFile19, rename as rename12, writeFile as writeFile16 } from "fs/promises";
31788
+ import { join as join22 } from "path";
31583
31789
  var START_MARKER = "<!-- absolutejs:deep-links:start -->";
31584
31790
  var END_MARKER = "<!-- absolutejs:deep-links:end -->";
31585
31791
  var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
31586
31792
  var NOT_FOUND = -1;
31587
31793
  var escapeXml = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
31588
31794
  var writeChangedFile = async (path, source) => {
31589
- const current = await readFile18(path, "utf8");
31795
+ const current = await readFile19(path, "utf8");
31590
31796
  if (current === source)
31591
31797
  return false;
31592
31798
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
@@ -31636,8 +31842,8 @@ ${hosts}
31636
31842
  `;
31637
31843
  };
31638
31844
  var configureAndroid = async (config) => {
31639
- const path = join21(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
31640
- const source = await readFile18(path, "utf8");
31845
+ const path = join22(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
31846
+ const source = await readFile19(path, "utf8");
31641
31847
  const mainActivity = source.indexOf('android:name=".MainActivity"');
31642
31848
  if (mainActivity === NOT_FOUND) {
31643
31849
  throw new TypeError("Android MainActivity was not found.");
@@ -31662,8 +31868,8 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
31662
31868
  ${END_MARKER}
31663
31869
  `;
31664
31870
  var configureIosInfo = async (config) => {
31665
- const path = join21(config.nativeProjectDirectory, "ios/App/App/Info.plist");
31666
- const source = await readFile18(path, "utf8");
31871
+ const path = join22(config.nativeProjectDirectory, "ios/App/App/Info.plist");
31872
+ const source = await readFile19(path, "utf8");
31667
31873
  const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
31668
31874
  ${END_MARKER}
31669
31875
  `;
@@ -31686,10 +31892,10 @@ ${domains}
31686
31892
  `;
31687
31893
  };
31688
31894
  var configureIosEntitlements = async (config) => {
31689
- const path = join21(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
31895
+ const path = join22(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
31690
31896
  let current = "";
31691
31897
  try {
31692
- current = await readFile18(path, "utf8");
31898
+ current = await readFile19(path, "utf8");
31693
31899
  } catch (error) {
31694
31900
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
31695
31901
  throw error;
@@ -31704,8 +31910,8 @@ var configureIosEntitlements = async (config) => {
31704
31910
  return true;
31705
31911
  };
31706
31912
  var configureIosProject = async (config) => {
31707
- const path = join21(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
31708
- const source = await readFile18(path, "utf8");
31913
+ const path = join22(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
31914
+ const source = await readFile19(path, "utf8");
31709
31915
  const declarations = [
31710
31916
  ...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
31711
31917
  ].map((match) => match[1]);
@@ -31744,8 +31950,8 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
31744
31950
  };
31745
31951
  // src/mobile/nativeDeviceCapabilities.ts
31746
31952
  init_deviceCapabilities();
31747
- import { readFile as readFile19, rename as rename13, writeFile as writeFile17 } from "fs/promises";
31748
- import { join as join22 } from "path";
31953
+ import { readFile as readFile20, rename as rename13, writeFile as writeFile17 } from "fs/promises";
31954
+ import { join as join23 } from "path";
31749
31955
  var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
31750
31956
  var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
31751
31957
  var NOT_FOUND2 = -1;
@@ -31755,7 +31961,7 @@ var PUSH_START_MARKER = "absolutejs:push-notifications:start";
31755
31961
  var PUSH_END_MARKER = "absolutejs:push-notifications:end";
31756
31962
  var escapeXml2 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
31757
31963
  var writeChangedFile2 = async (path, source) => {
31758
- const current = await readFile19(path, "utf8");
31964
+ const current = await readFile20(path, "utf8");
31759
31965
  if (current === source)
31760
31966
  return false;
31761
31967
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
@@ -31775,7 +31981,7 @@ var writeOptionalChangedFile = async (path, source) => {
31775
31981
  };
31776
31982
  var optionalSource = async (path) => {
31777
31983
  try {
31778
- return await readFile19(path, "utf8");
31984
+ return await readFile20(path, "utf8");
31779
31985
  } catch (error) {
31780
31986
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
31781
31987
  return null;
@@ -31895,8 +32101,8 @@ var writeIosPrivacyManifest = async (path, current, source) => {
31895
32101
  var configureIosPrivacyProject = async (config, requirements) => {
31896
32102
  if (requirements.iosPrivacyAccessedApis.length === 0)
31897
32103
  return false;
31898
- const projectPath2 = join22(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
31899
- const project = await readFile19(projectPath2, "utf8");
32104
+ const projectPath2 = join23(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
32105
+ const project = await readFile20(projectPath2, "utf8");
31900
32106
  return writeChangedFile2(projectPath2, addIosPrivacyProjectReference(project));
31901
32107
  };
31902
32108
  var addIosPrivacyProjectReference = (source) => {
@@ -31948,8 +32154,8 @@ ${next.slice(index)}`;
31948
32154
  return next;
31949
32155
  };
31950
32156
  var configureIos2 = async (config, plan) => {
31951
- const path = join22(config.nativeProjectDirectory, "ios/App/App/Info.plist");
31952
- const source = await readFile19(path, "utf8");
32157
+ const path = join23(config.nativeProjectDirectory, "ios/App/App/Info.plist");
32158
+ const source = await readFile20(path, "utf8");
31953
32159
  const requirements = absoluteDeviceNativeRequirements(plan);
31954
32160
  const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
31955
32161
  const ownedStart = source.indexOf(START_MARKER2);
@@ -31969,7 +32175,7 @@ ${content}
31969
32175
  ${END_MARKER2}
31970
32176
  ` : "";
31971
32177
  const infoChanged = await writeChangedFile2(path, managed(source, region, source.lastIndexOf("</dict>")));
31972
- const privacyPath = join22(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
32178
+ const privacyPath = join23(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
31973
32179
  const privacyCurrent = await optionalSource(privacyPath);
31974
32180
  const privacySource = privacyManifestSource(privacyCurrent, requirements);
31975
32181
  const [privacyChanged, projectChanged, pushChanged] = await Promise.all([
@@ -31980,7 +32186,7 @@ ${content}
31980
32186
  return infoChanged || privacyChanged || projectChanged || pushChanged;
31981
32187
  };
31982
32188
  var configureIosPushNotifications = async (config, enabled) => {
31983
- const entitlementsPath = join22(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
32189
+ const entitlementsPath = join23(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
31984
32190
  const entitlements = await optionalSource(entitlementsPath);
31985
32191
  if (entitlements === null && !enabled)
31986
32192
  return false;
@@ -31992,7 +32198,7 @@ var configureIosPushNotifications = async (config, enabled) => {
31992
32198
  <!-- ${PUSH_END_MARKER} -->
31993
32199
  ` : "";
31994
32200
  const nextEntitlements = replacePushRegion(entitlements, entitlementRegion, entitlements.lastIndexOf("</dict>"));
31995
- const delegatePath = join22(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
32201
+ const delegatePath = join23(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
31996
32202
  const delegate = await optionalSource(delegatePath);
31997
32203
  if (delegate === null && !enabled)
31998
32204
  return false;
@@ -32041,8 +32247,8 @@ var replacePushRegion = (source, region, insertion) => {
32041
32247
  return `${source.slice(0, insertion)}${region}${source.slice(insertion)}`;
32042
32248
  };
32043
32249
  var configureAndroid2 = async (config, plan) => {
32044
- const path = join22(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
32045
- const source = await readFile19(path, "utf8");
32250
+ const path = join23(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
32251
+ const source = await readFile20(path, "utf8");
32046
32252
  const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
32047
32253
  const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
32048
32254
  `);
@@ -32077,7 +32283,7 @@ ${content}
32077
32283
  throw new TypeError(`Android google-services.json does not contain package ${config.appId}.`);
32078
32284
  const [manifestChanged, firebaseChanged] = await Promise.all([
32079
32285
  writeChangedFile2(path, nextManifest),
32080
- writeOptionalChangedFile(join22(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
32286
+ writeOptionalChangedFile(join23(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
32081
32287
  ]);
32082
32288
  return manifestChanged || firebaseChanged;
32083
32289
  };
@@ -32097,13 +32303,13 @@ init_nativeAuth();
32097
32303
  // src/mobile/nativeUpdates.ts
32098
32304
  import {
32099
32305
  mkdir as mkdir15,
32100
- readFile as readFile20,
32101
- readdir as readdir5,
32306
+ readFile as readFile21,
32307
+ readdir as readdir6,
32102
32308
  rename as rename14,
32103
32309
  rm as rm11,
32104
32310
  writeFile as writeFile18
32105
32311
  } from "fs/promises";
32106
- import { dirname as dirname15, join as join23 } from "path";
32312
+ import { dirname as dirname15, join as join24 } from "path";
32107
32313
  var START = "// absolutejs:mobile-updates:start";
32108
32314
  var END = "// absolutejs:mobile-updates:end";
32109
32315
  var PLUGIN_START = "// absolutejs:mobile-update-plugin:start";
@@ -32111,7 +32317,7 @@ var PLUGIN_END = "// absolutejs:mobile-update-plugin:end";
32111
32317
  var ANDROID_PLUGIN = "AbsoluteMobileUpdateWatchdogPlugin.java";
32112
32318
  var optionalSource2 = async (path) => {
32113
32319
  try {
32114
- return await readFile20(path, "utf8");
32320
+ return await readFile21(path, "utf8");
32115
32321
  } catch (error) {
32116
32322
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
32117
32323
  return null;
@@ -32273,9 +32479,9 @@ public final class AbsoluteMobileUpdateWatchdogPlugin: CAPPlugin, CAPBridgedPlug
32273
32479
  ${PLUGIN_END}
32274
32480
  `;
32275
32481
  var configureIos3 = async (config, enabled) => {
32276
- const path = join23(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
32277
- const capacitorConfigPath = join23(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
32278
- let source = await readFile20(path, "utf8");
32482
+ const path = join24(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
32483
+ const capacitorConfigPath = join24(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
32484
+ let source = await readFile21(path, "utf8");
32279
32485
  const launch = source.indexOf("didFinishLaunchingWithOptions");
32280
32486
  const brace = launch < 0 ? -1 : source.indexOf("{", launch);
32281
32487
  const launchRegion = enabled ? ` ${START}
@@ -32286,7 +32492,7 @@ var configureIos3 = async (config, enabled) => {
32286
32492
  `, brace) + 1, "Could not find a safe iOS location for mobile update recovery.");
32287
32493
  const plugin = enabled ? iosPluginRegion(config.updates?.bootTimeoutMs ?? 20000) : "";
32288
32494
  source = replaceMarkedRegion(source, PLUGIN_START, PLUGIN_END, plugin, source.length, "Could not find a safe iOS location for the mobile update watchdog.");
32289
- const capacitorConfigSource2 = await readFile20(capacitorConfigPath, "utf8");
32495
+ const capacitorConfigSource2 = await readFile21(capacitorConfigPath, "utf8");
32290
32496
  let capacitorConfig;
32291
32497
  try {
32292
32498
  const value = JSON.parse(capacitorConfigSource2);
@@ -32459,19 +32665,19 @@ public final class AbsoluteMobileUpdateWatchdogPlugin extends Plugin {
32459
32665
  var androidActivityInRoot = async (root) => {
32460
32666
  let entries;
32461
32667
  try {
32462
- entries = await readdir5(root, { recursive: true });
32668
+ entries = await readdir6(root, { recursive: true });
32463
32669
  } catch (error) {
32464
32670
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
32465
32671
  return;
32466
32672
  throw error;
32467
32673
  }
32468
32674
  const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
32469
- return candidate ? join23(root, candidate) : undefined;
32675
+ return candidate ? join24(root, candidate) : undefined;
32470
32676
  };
32471
32677
  var androidActivity = async (config) => {
32472
32678
  const roots = [
32473
- join23(config.nativeProjectDirectory, "android/app/src/main/java"),
32474
- join23(config.nativeProjectDirectory, "android/app/src/main/kotlin")
32679
+ join24(config.nativeProjectDirectory, "android/app/src/main/java"),
32680
+ join24(config.nativeProjectDirectory, "android/app/src/main/kotlin")
32475
32681
  ];
32476
32682
  const candidates = await Promise.all(roots.map(androidActivityInRoot));
32477
32683
  const candidate = candidates.find((value) => value !== undefined);
@@ -32570,12 +32776,12 @@ var injectAndroidActivity = (source, enabled) => {
32570
32776
  };
32571
32777
  var configureAndroid3 = async (config, enabled) => {
32572
32778
  const activityPath = await androidActivity(config);
32573
- const activity = await readFile20(activityPath, "utf8");
32779
+ const activity = await readFile21(activityPath, "utf8");
32574
32780
  const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
32575
32781
  if (!packageName)
32576
32782
  throw new TypeError("Android MainActivity package declaration was not found.");
32577
32783
  const packagePath = packageName.replaceAll(".", "/");
32578
- const pluginPath = join23(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
32784
+ const pluginPath = join24(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
32579
32785
  const changed = await Promise.all([
32580
32786
  writeChanged(activityPath, injectAndroidActivity(activity, enabled)),
32581
32787
  enabled ? writeChanged(pluginPath, androidPluginSource(packageName, config.updates?.bootTimeoutMs ?? 20000)) : removeOwnedFile(pluginPath)
@@ -32596,13 +32802,13 @@ var applyAbsoluteNativeUpdates = async (config, platforms = config.platforms) =>
32596
32802
  // src/mobile/nativeObservability.ts
32597
32803
  import {
32598
32804
  mkdir as mkdir16,
32599
- readFile as readFile21,
32600
- readdir as readdir6,
32805
+ readFile as readFile22,
32806
+ readdir as readdir7,
32601
32807
  rename as rename15,
32602
32808
  rm as rm12,
32603
32809
  writeFile as writeFile19
32604
32810
  } from "fs/promises";
32605
- import { dirname as dirname16, join as join24 } from "path";
32811
+ import { dirname as dirname16, join as join25 } from "path";
32606
32812
  var START2 = "// absolutejs:native-observability:start";
32607
32813
  var END2 = "// absolutejs:native-observability:end";
32608
32814
  var PLUGIN_START2 = "// absolutejs:native-observability-plugin:start";
@@ -32610,7 +32816,7 @@ var PLUGIN_END2 = "// absolutejs:native-observability-plugin:end";
32610
32816
  var ANDROID_PLUGIN2 = "AbsoluteMobileObservabilityPlugin.java";
32611
32817
  var optionalSource3 = async (path) => {
32612
32818
  try {
32613
- return await readFile21(path, "utf8");
32819
+ return await readFile22(path, "utf8");
32614
32820
  } catch (error) {
32615
32821
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
32616
32822
  return null;
@@ -32770,9 +32976,9 @@ public final class AbsoluteMobileObservabilityPlugin: CAPPlugin, CAPBridgedPlugi
32770
32976
  ${PLUGIN_END2}
32771
32977
  `;
32772
32978
  var configureIos4 = async (config, enabled) => {
32773
- const path = join24(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
32774
- const capacitorConfigPath = join24(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
32775
- let source = await readFile21(path, "utf8");
32979
+ const path = join25(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
32980
+ const capacitorConfigPath = join25(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
32981
+ let source = await readFile22(path, "utf8");
32776
32982
  if (enabled && !source.includes("import MetricKit")) {
32777
32983
  const capacitorImport = source.lastIndexOf("import Capacitor");
32778
32984
  if (capacitorImport < 0)
@@ -32786,7 +32992,7 @@ ${source.slice(newline + 1)}`;
32786
32992
  source = source.replace(`import MetricKit
32787
32993
  `, "");
32788
32994
  source = replaceMarkedRegion2(source, PLUGIN_START2, PLUGIN_END2, enabled ? iosPluginRegion2 : "", source.length, "Could not find a safe iOS location for native observability.");
32789
- const capacitorConfigSource2 = await readFile21(capacitorConfigPath, "utf8");
32995
+ const capacitorConfigSource2 = await readFile22(capacitorConfigPath, "utf8");
32790
32996
  let capacitorConfig;
32791
32997
  try {
32792
32998
  const value = JSON.parse(capacitorConfigSource2);
@@ -33024,19 +33230,19 @@ public final class AbsoluteMobileObservabilityPlugin extends Plugin {
33024
33230
  var androidActivityInRoot2 = async (root) => {
33025
33231
  let entries;
33026
33232
  try {
33027
- entries = await readdir6(root, { recursive: true });
33233
+ entries = await readdir7(root, { recursive: true });
33028
33234
  } catch (error) {
33029
33235
  if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
33030
33236
  return;
33031
33237
  throw error;
33032
33238
  }
33033
33239
  const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
33034
- return candidate ? join24(root, candidate) : undefined;
33240
+ return candidate ? join25(root, candidate) : undefined;
33035
33241
  };
33036
33242
  var androidActivity2 = async (config) => {
33037
33243
  const roots = [
33038
- join24(config.nativeProjectDirectory, "android/app/src/main/java"),
33039
- join24(config.nativeProjectDirectory, "android/app/src/main/kotlin")
33244
+ join25(config.nativeProjectDirectory, "android/app/src/main/java"),
33245
+ join25(config.nativeProjectDirectory, "android/app/src/main/kotlin")
33040
33246
  ];
33041
33247
  const candidates = await Promise.all(roots.map(androidActivityInRoot2));
33042
33248
  const candidate = candidates.find((value) => value !== undefined);
@@ -33104,11 +33310,11 @@ var injectAndroidActivity2 = (source, enabled) => {
33104
33310
  };
33105
33311
  var configureAndroid4 = async (config, enabled) => {
33106
33312
  const activityPath = await androidActivity2(config);
33107
- const activity = await readFile21(activityPath, "utf8");
33313
+ const activity = await readFile22(activityPath, "utf8");
33108
33314
  const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
33109
33315
  if (!packageName)
33110
33316
  throw new TypeError("Android MainActivity package declaration was not found.");
33111
- const pluginPath = join24(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
33317
+ const pluginPath = join25(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
33112
33318
  const changed = await Promise.all([
33113
33319
  writeChanged2(activityPath, injectAndroidActivity2(activity, enabled)),
33114
33320
  enabled ? writeChanged2(pluginPath, androidPluginSource2(packageName)) : removeOwnedFile2(pluginPath)
@@ -33133,8 +33339,8 @@ init_producerContext();
33133
33339
  init_releaseArtifact();
33134
33340
 
33135
33341
  // src/mobile/releasePublisher.ts
33136
- import { access as access14 } from "fs/promises";
33137
- import { isAbsolute as isAbsolute7, relative as relative13, resolve as resolve16, sep as sep9 } from "path";
33342
+ import { access as access15 } from "fs/promises";
33343
+ import { isAbsolute as isAbsolute7, relative as relative14, resolve as resolve16, sep as sep9 } from "path";
33138
33344
  import { pathToFileURL as pathToFileURL3 } from "url";
33139
33345
  var prepareAbsoluteIosRelease = async (publisher, options) => {
33140
33346
  if (typeof publisher.prepareIosRelease !== "function") {
@@ -33162,7 +33368,7 @@ var isPublisher = (value) => isRecord13(value) && typeof value.publish === "func
33162
33368
  var publisherModulePath = (projectRoot, requested) => {
33163
33369
  const root = resolve16(projectRoot);
33164
33370
  const path = resolve16(root, requested);
33165
- const projectRelative = relative13(root, path);
33371
+ const projectRelative = relative14(root, path);
33166
33372
  if (projectRelative === ".." || projectRelative.startsWith(`..${sep9}`) || isAbsolute7(projectRelative)) {
33167
33373
  throw new TypeError("mobile publish --registry must remain inside the project.");
33168
33374
  }
@@ -33170,7 +33376,7 @@ var publisherModulePath = (projectRoot, requested) => {
33170
33376
  };
33171
33377
  var loadAbsoluteNativeReleasePublisher = async (projectRoot, requestedModulePath) => {
33172
33378
  const modulePath = publisherModulePath(projectRoot, requestedModulePath);
33173
- await access14(modulePath).catch(() => {
33379
+ await access15(modulePath).catch(() => {
33174
33380
  throw new TypeError(`Native release registry module does not exist: ${modulePath}`);
33175
33381
  });
33176
33382
  const loaded = await import(pathToFileURL3(modulePath).href);
@@ -33234,7 +33440,7 @@ var publishAbsoluteIosRelease = async (options) => {
33234
33440
  init_pageProtocol();
33235
33441
  init_releaseArtifact();
33236
33442
  import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
33237
- import { dirname as dirname17, extname as extname6, relative as relative14, resolve as resolve17 } from "path";
33443
+ import { dirname as dirname17, extname as extname6, relative as relative15, resolve as resolve17 } from "path";
33238
33444
  import ts2 from "typescript";
33239
33445
  var ROUTE_METHODS = new Set(["get", "head"]);
33240
33446
  var SOURCE_FILTER = /\.[cm]?[jt]sx?$/;
@@ -33403,7 +33609,7 @@ var resolvePageIdentity = (expression, sourceFile, checker, projectRoot) => {
33403
33609
  const declaration = symbol?.declarations?.[0];
33404
33610
  const file = declaration?.getSourceFile().fileName ?? sourceFile.fileName;
33405
33611
  const exportedName = symbol?.name ?? expression.getText(sourceFile);
33406
- const source = posixPath(relative14(projectRoot, file));
33612
+ const source = posixPath(relative15(projectRoot, file));
33407
33613
  return `${source}#${exportedName}`;
33408
33614
  };
33409
33615
  var resolveAlias = (symbol, checker) => {
@@ -33759,7 +33965,7 @@ var inspectAbsoluteMobileRouteMetadata = (options) => {
33759
33965
  const entry = resolve17(options.entry);
33760
33966
  const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
33761
33967
  return [...analyzed.entries()].flatMap(([file, analysis]) => [...analysis.byRouteCall.values()].map(({ metadata }) => ({
33762
- file: posixPath(relative14(projectRoot, file)),
33968
+ file: posixPath(relative15(projectRoot, file)),
33763
33969
  metadata
33764
33970
  })));
33765
33971
  };
@@ -37756,7 +37962,7 @@ var createBeacon = (options) => {
37756
37962
  if (signals !== null && signals.mediaFailures !== false && typeof document !== "undefined") {
37757
37963
  const stallMs = signals.mediaStallMs ?? MEDIA_STALL_DEFAULT_MS;
37758
37964
  const watched = new Map;
37759
- const watch2 = (media) => {
37965
+ const watch3 = (media) => {
37760
37966
  if (watched.has(media) || !media.hasAttribute(BEACON_ATTRIBUTE.MEDIA))
37761
37967
  return;
37762
37968
  const name = media.getAttribute(BEACON_ATTRIBUTE.MEDIA)?.trim() || describeElement(media);
@@ -37817,10 +38023,10 @@ var createBeacon = (options) => {
37817
38023
  };
37818
38024
  const scan = (root) => {
37819
38025
  if (root instanceof HTMLMediaElement)
37820
- watch2(root);
38026
+ watch3(root);
37821
38027
  for (const media of Array.from(root.querySelectorAll?.(`audio[${BEACON_ATTRIBUTE.MEDIA}], video[${BEACON_ATTRIBUTE.MEDIA}]`) ?? [])) {
37822
38028
  if (media instanceof HTMLMediaElement)
37823
- watch2(media);
38029
+ watch3(media);
37824
38030
  }
37825
38031
  };
37826
38032
  scan(document);
@@ -37870,7 +38076,7 @@ var createBeacon = (options) => {
37870
38076
  const originalOpen = factory.open.bind(factory);
37871
38077
  const originalDeleteDatabase = factory.deleteDatabase.bind(factory);
37872
38078
  const reported = new WeakSet;
37873
- const watch2 = (request, operation2, database) => {
38079
+ const watch3 = (request, operation2, database) => {
37874
38080
  request.addEventListener("error", () => {
37875
38081
  if (reported.has(request))
37876
38082
  return;
@@ -37886,8 +38092,8 @@ var createBeacon = (options) => {
37886
38092
  }, { once: true });
37887
38093
  return request;
37888
38094
  };
37889
- const wrappedOpen = (name, version) => watch2(version === undefined ? originalOpen(name) : originalOpen(name, version), "open", name);
37890
- const wrappedDeleteDatabase = (name) => watch2(originalDeleteDatabase(name), "delete", name);
38095
+ const wrappedOpen = (name, version) => watch3(version === undefined ? originalOpen(name) : originalOpen(name, version), "open", name);
38096
+ const wrappedDeleteDatabase = (name) => watch3(originalDeleteDatabase(name), "delete", name);
37891
38097
  try {
37892
38098
  factory.open = wrappedOpen;
37893
38099
  factory.deleteDatabase = wrappedDeleteDatabase;
@@ -39951,44 +40157,44 @@ var createAbsoluteMobileUpdateClient = (options) => {
39951
40157
  };
39952
40158
  };
39953
40159
  // src/mobile/updatePublisher.ts
39954
- import { access as access15 } from "fs/promises";
39955
- import { isAbsolute as isAbsolute8, relative as relative16, resolve as resolve19, sep as sep10 } from "path";
40160
+ import { access as access16 } from "fs/promises";
40161
+ import { isAbsolute as isAbsolute8, relative as relative17, resolve as resolve19, sep as sep10 } from "path";
39956
40162
  import { pathToFileURL as pathToFileURL4 } from "url";
39957
40163
 
39958
40164
  // src/mobile/updateSigning.ts
39959
- import { createHash as createHash13, sign, verify } from "crypto";
40165
+ import { createHash as createHash14, sign, verify } from "crypto";
39960
40166
  import {
39961
40167
  cp as cp3,
39962
40168
  mkdir as mkdir17,
39963
40169
  mkdtemp as mkdtemp8,
39964
- readdir as readdir7,
39965
- readFile as readFile22,
40170
+ readdir as readdir8,
40171
+ readFile as readFile23,
39966
40172
  rename as rename16,
39967
40173
  rm as rm13,
39968
40174
  stat as stat4,
39969
40175
  writeFile as writeFile20
39970
40176
  } from "fs/promises";
39971
- import { dirname as dirname18, join as join25, relative as relative15, resolve as resolve18 } from "path";
40177
+ import { dirname as dirname18, join as join26, relative as relative16, resolve as resolve18 } from "path";
39972
40178
  var UPDATE_MANIFEST_FILE = "update.json";
39973
40179
  var UPDATE_FILES_DIRECTORY = "files";
39974
- var sha2562 = (value) => createHash13("sha256").update(value).digest("hex");
40180
+ var sha2562 = (value) => createHash14("sha256").update(value).digest("hex");
39975
40181
  var listFiles = async (root, directory = root) => {
39976
- const entries = await readdir7(directory, { withFileTypes: true });
40182
+ const entries = await readdir8(directory, { withFileTypes: true });
39977
40183
  const paths = await Promise.all(entries.map(async (entry) => {
39978
- const path = join25(directory, entry.name);
40184
+ const path = join26(directory, entry.name);
39979
40185
  if (entry.isDirectory())
39980
40186
  return listFiles(root, path);
39981
40187
  if (!entry.isFile())
39982
40188
  throw new TypeError("Mobile updates cannot contain links or special files.");
39983
- return [relative15(root, path).replaceAll("\\", "/")];
40189
+ return [relative16(root, path).replaceAll("\\", "/")];
39984
40190
  }));
39985
40191
  return paths.flat().sort((left, right) => left.localeCompare(right));
39986
40192
  };
39987
40193
  var inspectFiles = async (root, paths) => Promise.all(paths.map(async (path) => {
39988
- const source = join25(root, path);
40194
+ const source = join26(root, path);
39989
40195
  const [metadata, contents] = await Promise.all([
39990
40196
  stat4(source),
39991
- readFile22(source)
40197
+ readFile23(source)
39992
40198
  ]);
39993
40199
  return { bytes: metadata.size, path, sha256: sha2562(contents) };
39994
40200
  }));
@@ -40024,14 +40230,14 @@ var buildAbsoluteMobileUpdate = async (options) => {
40024
40230
  }
40025
40231
  });
40026
40232
  await mkdir17(outputRoot, { recursive: true });
40027
- const outputDirectory = join25(outputRoot, manifest.releaseId);
40028
- const staging = await mkdtemp8(join25(outputRoot, ".stage-"));
40233
+ const outputDirectory = join26(outputRoot, manifest.releaseId);
40234
+ const staging = await mkdtemp8(join26(outputRoot, ".stage-"));
40029
40235
  try {
40030
- await cp3(bundleDirectory, join25(staging, UPDATE_FILES_DIRECTORY), {
40236
+ await cp3(bundleDirectory, join26(staging, UPDATE_FILES_DIRECTORY), {
40031
40237
  force: true,
40032
40238
  recursive: true
40033
40239
  });
40034
- await writeFile20(join25(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
40240
+ await writeFile20(join26(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
40035
40241
  `);
40036
40242
  await rename16(staging, outputDirectory);
40037
40243
  } catch (error) {
@@ -40042,7 +40248,7 @@ var buildAbsoluteMobileUpdate = async (options) => {
40042
40248
  }
40043
40249
  return {
40044
40250
  manifest,
40045
- manifestPath: join25(outputDirectory, UPDATE_MANIFEST_FILE),
40251
+ manifestPath: join26(outputDirectory, UPDATE_MANIFEST_FILE),
40046
40252
  outputDirectory
40047
40253
  };
40048
40254
  };
@@ -40054,7 +40260,7 @@ var copyAbsoluteMobileUpdateFile = async (updateDirectory, path, destination) =>
40054
40260
  await mkdir17(dirname18(destination), { recursive: true });
40055
40261
  await cp3(source, destination, { force: true });
40056
40262
  };
40057
- var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile22(join25(resolve18(directory), UPDATE_MANIFEST_FILE), "utf8")));
40263
+ var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile23(join26(resolve18(directory), UPDATE_MANIFEST_FILE), "utf8")));
40058
40264
  var verifyAbsoluteMobileUpdateSignature = (manifestValue, publicKey) => {
40059
40265
  const manifest = parseAbsoluteMobileUpdateManifest(manifestValue);
40060
40266
  const valid = verify("sha256", absoluteMobileUpdateSigningPayload(unsignedAbsoluteMobileUpdate(manifest)), { dsaEncoding: "ieee-p1363", key: publicKey }, Buffer.from(manifest.signature.value, "base64"));
@@ -40173,14 +40379,14 @@ var isPublisher2 = (value) => object5(value) && typeof value.publishUpdate === "
40173
40379
  var projectPath2 = (projectRoot, requested, label) => {
40174
40380
  const root = resolve19(projectRoot);
40175
40381
  const path = resolve19(root, requested);
40176
- const projectRelative = relative16(root, path);
40382
+ const projectRelative = relative17(root, path);
40177
40383
  if (projectRelative === ".." || projectRelative.startsWith(`..${sep10}`) || isAbsolute8(projectRelative))
40178
40384
  throw new TypeError(`${label} must remain inside the project.`);
40179
40385
  return path;
40180
40386
  };
40181
40387
  var loadAbsoluteMobileUpdatePublisher = async (projectRoot, requestedModulePath) => {
40182
40388
  const modulePath = projectPath2(projectRoot, requestedModulePath, "mobile update registry");
40183
- await access15(modulePath).catch(() => {
40389
+ await access16(modulePath).catch(() => {
40184
40390
  throw new TypeError(`Mobile update registry does not exist: ${modulePath}`);
40185
40391
  });
40186
40392
  const loaded = await import(pathToFileURL4(modulePath).href);
@@ -40231,7 +40437,7 @@ var rollbackAbsoluteMobileUpdate = async (options) => {
40231
40437
  return result;
40232
40438
  };
40233
40439
  // src/mobile/updateRollout.ts
40234
- import { createHash as createHash14 } from "crypto";
40440
+ import { createHash as createHash15 } from "crypto";
40235
40441
  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;
40236
40442
  var requireHeader = (headers, name) => {
40237
40443
  const value = headers.get(name);
@@ -40246,7 +40452,7 @@ var isAbsoluteMobileUpdateRolloutMember = (options) => {
40246
40452
  return false;
40247
40453
  if (options.rollout === 1)
40248
40454
  return true;
40249
- const digest = createHash14("sha256").update(`${options.appId}\x00${options.channel}\x00${options.releaseId}\x00${options.installationId}`).digest();
40455
+ const digest = createHash15("sha256").update(`${options.appId}\x00${options.channel}\x00${options.releaseId}\x00${options.installationId}`).digest();
40250
40456
  const bucket = digest.readUInt32BE(0) / 4294967296;
40251
40457
  return bucket < options.rollout;
40252
40458
  };
@@ -40353,6 +40559,7 @@ export {
40353
40559
  copyAbsoluteMobileUpdateFile,
40354
40560
  createAbsoluteExpoBridgeError,
40355
40561
  createAbsoluteExpoBridgeResponse,
40562
+ createAbsoluteExpoNativeWatcher,
40356
40563
  createAbsoluteIosNativeWatcher,
40357
40564
  createAbsoluteMobileAssociationDocuments,
40358
40565
  createAbsoluteMobileAssociationPlugin,
@@ -40384,6 +40591,7 @@ export {
40384
40591
  finalizeAbsoluteMobileCompatibilityBuild,
40385
40592
  finalizeAbsoluteMobilePage,
40386
40593
  finalizeAbsoluteRouteData,
40594
+ fingerprintAbsoluteExpoNativeInputs,
40387
40595
  fingerprintAbsoluteIosDevProject,
40388
40596
  fingerprintAbsoluteIosNativeProject,
40389
40597
  fingerprintAbsoluteMobileUpdateRuntime,
@@ -40412,6 +40620,7 @@ export {
40412
40620
  installAbsoluteMobileSyncRemediation,
40413
40621
  installAbsoluteMobileUiPrimitives,
40414
40622
  installAbsoluteRemoteMacAgent,
40623
+ isAbsoluteExpoNativeRootInput,
40415
40624
  isAbsoluteIosNativeRootInput,
40416
40625
  isAbsoluteMobileUpdateRolloutMember,
40417
40626
  listAbsoluteRemoteMacProfiles,
@@ -40512,5 +40721,5 @@ export {
40512
40721
  writeAbsoluteMobileUpdateRegistry
40513
40722
  };
40514
40723
 
40515
- //# debugId=8D376EB1B818995C64756E2164756E21
40724
+ //# debugId=B619FED6B184271164756E2164756E21
40516
40725
  //# sourceMappingURL=index.js.map