@absolutejs/absolute 0.20.0-beta.87 → 0.20.0-beta.89

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.
@@ -20404,6 +20404,17 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20404
20404
  });
20405
20405
  return value;
20406
20406
  };
20407
+ const readHealthPause = async (channel) => {
20408
+ if (!channel.releaseId)
20409
+ return null;
20410
+ const promotionId = healthPromotionId(channel);
20411
+ const value = await readVerifiedObject(pauseKey(channel.appId, promotionId, channel.releaseId), "health pause");
20412
+ if (value === null)
20413
+ return null;
20414
+ if (!object6(value) || value.format !== 1 || value.appId !== channel.appId || value.channel !== channel.channel || value.promotionId !== promotionId || value.releaseId !== channel.releaseId || typeof value.failureRate !== "number" || !Number.isFinite(value.failureRate) || value.failureRate < 0 || value.failureRate > 1 || !Number.isSafeInteger(value.failures) || Number(value.failures) < 0 || !Number.isSafeInteger(value.reports) || Number(value.reports) < 1 || !iso(value.pausedAt))
20415
+ throw new MobileUpdateRegistryError("Stored mobile update health pause is invalid");
20416
+ return value;
20417
+ };
20407
20418
  const rolloutContext = async (channel) => {
20408
20419
  if (!options.store.list || !channel.releaseId)
20409
20420
  return null;
@@ -20435,18 +20446,31 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20435
20446
  throw new MobileUpdateRegistryError("Stored mobile update rollout control is invalid");
20436
20447
  parsedControls.push(value);
20437
20448
  }
20449
+ parsedControls.sort((left, right) => left.createdAt.localeCompare(right.createdAt) || left.id.localeCompare(right.id));
20438
20450
  const cancelled = parsedControls.some(({ action }) => action === "cancel");
20439
20451
  const resumedPauseIds = new Set(parsedControls.flatMap((control) => control.resumedPauseIds ?? []));
20440
- const activePauseIds = parsedControls.filter(({ action, id }) => action === "pause" && !resumedPauseIds.has(id)).map(({ id }) => id);
20452
+ const activePauseControls = parsedControls.filter(({ action, id }) => action === "pause" && !resumedPauseIds.has(id));
20453
+ const activePauseIds = activePauseControls.map(({ id }) => id);
20441
20454
  const operatorPaused = activePauseIds.length > 0;
20442
- const fleetPaused = Boolean(await options.store.head(pauseKey(channel.appId, promotionId, channel.releaseId)));
20455
+ const fleetPause = await readHealthPause(channel);
20456
+ const fleetPaused = fleetPause !== null;
20457
+ const transitionControl = parsedControls.find(({ action }) => action === "cancel") ?? activePauseControls.at(-1) ?? parsedControls.findLast(({ action }) => action === "resume");
20458
+ const latestTransition = fleetPause && (!transitionControl || fleetPause.pausedAt > transitionControl.createdAt) ? {
20459
+ activatedAt: fleetPause.pausedAt,
20460
+ activationId: digest(new TextEncoder().encode(`${promotionId}\x00fleet-pause\x00${fleetPause.pausedAt}`))
20461
+ } : transitionControl ? {
20462
+ activatedAt: transitionControl.createdAt,
20463
+ activationId: digest(new TextEncoder().encode(`${promotionId}\x00control\x00${transitionControl.id}\x00${transitionControl.action}`))
20464
+ } : undefined;
20443
20465
  return {
20466
+ ...latestTransition,
20444
20467
  cancelled,
20445
20468
  activePauseIds,
20446
20469
  channel,
20447
20470
  currentStage,
20448
20471
  enteredAt,
20449
20472
  fleetPaused,
20473
+ fleetPause,
20450
20474
  operatorPaused,
20451
20475
  plan,
20452
20476
  promotionId,
@@ -20515,6 +20539,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20515
20539
  if (!channel?.releaseId)
20516
20540
  return { status: "empty" };
20517
20541
  const rolloutState = await rolloutContext(channel);
20542
+ const healthPause = rolloutState?.fleetPause ?? (health ? await readHealthPause(channel) : null);
20518
20543
  let selected = rolloutMember({
20519
20544
  appId: input.appId,
20520
20545
  channel: input.channel,
@@ -20522,7 +20547,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20522
20547
  releaseId: channel.releaseId,
20523
20548
  rollout: rolloutState?.rollout ?? channel.rollout
20524
20549
  }) ? channel.releaseId : channel.fallbackReleaseId;
20525
- if (selected === channel.releaseId && (rolloutState?.cancelled || rolloutState?.fleetPaused || rolloutState?.operatorPaused || health && await options.store.head(pauseKey(input.appId, healthPromotionId(channel), channel.releaseId))))
20550
+ if (selected === channel.releaseId && (rolloutState?.cancelled || rolloutState?.fleetPaused || rolloutState?.operatorPaused || healthPause))
20526
20551
  selected = channel.fallbackReleaseId;
20527
20552
  if (!selected)
20528
20553
  return { status: "empty" };
@@ -20530,7 +20555,13 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
20530
20555
  if (!release || release.manifest.runtimeFingerprint !== input.runtimeFingerprint)
20531
20556
  return { status: "incompatible" };
20532
20557
  return {
20533
- ...selected === channel.releaseId && channel.activationId && channel.activatedAt ? {
20558
+ ...rolloutState?.activationId && rolloutState.activatedAt ? {
20559
+ activationId: rolloutState.activationId,
20560
+ activatedAt: rolloutState.activatedAt
20561
+ } : healthPause ? {
20562
+ activatedAt: healthPause.pausedAt,
20563
+ activationId: digest(new TextEncoder().encode(`${healthPromotionId(channel)}\x00fleet-pause\x00${healthPause.pausedAt}`))
20564
+ } : selected === channel.releaseId && channel.activationId && channel.activatedAt ? {
20534
20565
  activationId: channel.activationId,
20535
20566
  activatedAt: channel.activatedAt
20536
20567
  } : {},
@@ -21414,7 +21445,9 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21414
21445
  const platform5 = request.headers.get("expo-platform");
21415
21446
  if (platform5 !== "android" && platform5 !== "ios")
21416
21447
  return new Response(null, { status: 400 });
21417
- const updateId = expoUpdateId((resolution?.status === "selected" ? resolution.activationId : undefined) ?? selected.manifest.releaseId);
21448
+ const activationId = resolution?.status === "selected" ? resolution.activationId : undefined;
21449
+ const activatedAt = resolution?.status === "selected" ? resolution.activatedAt : undefined;
21450
+ const updateId = expoUpdateId(activationId ?? selected.manifest.releaseId);
21418
21451
  if (request.headers.get("expo-current-update-id") === updateId)
21419
21452
  return new Response(null, { status: 204 });
21420
21453
  const descriptorFile = await options.registry.readUpdateFile({
@@ -21444,7 +21477,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
21444
21477
  };
21445
21478
  const manifest = JSON.stringify({
21446
21479
  assets: platformUpdate.assets.map((asset2) => protocolAsset(asset2)),
21447
- createdAt: (resolution?.status === "selected" ? resolution.activatedAt : undefined) ?? selected.manifest.createdAt,
21480
+ createdAt: activatedAt ?? selected.manifest.createdAt,
21448
21481
  extra: {
21449
21482
  absolutejs: {
21450
21483
  channel: selected.manifest.channel,
@@ -32004,9 +32037,12 @@ public final class AbsoluteMobileUpdateWatchdogPlugin: CAPPlugin, CAPBridgedPlug
32004
32037
  private static func recover(_ reason: String) -> (String, String?, Bool)? {
32005
32038
  var value = state()
32006
32039
  guard let release = value["pendingRelease"] as? String, validRelease(release) else { return nil }
32007
- let previous = value["previousPath"] as? String
32008
32040
  let active = value["activeRelease"] as? String
32009
- let hasActive = active.map(validRelease) ?? false
32041
+ let activePath = active.flatMap { candidate in
32042
+ validRelease(candidate) ? snapshotRoot()?.appendingPathComponent(candidate, isDirectory: true).path : nil
32043
+ }
32044
+ let hasActive = activePath.map { FileManager.default.fileExists(atPath: $0) } ?? false
32045
+ let previous = hasActive ? activePath : nil
32010
32046
  let started = value["pendingStartedAt"] as? Double ?? Date().timeIntervalSince1970 * 1000
32011
32047
  let duration = max(0, Date().timeIntervalSince1970 * 1000 - started)
32012
32048
  value.removeValue(forKey: "pendingRelease")
@@ -32178,8 +32214,10 @@ public final class AbsoluteMobileUpdateWatchdogPlugin extends Plugin {
32178
32214
  JSONObject value = state(context);
32179
32215
  String release = value.optString("pendingRelease", "");
32180
32216
  if (!validRelease(release)) return null;
32181
- String previous = value.optString("previousPath", "");
32182
- boolean hasActive = validRelease(value.optString("activeRelease", ""));
32217
+ String activeRelease = value.optString("activeRelease", "");
32218
+ File activePath = new File(snapshotRoot(context), activeRelease);
32219
+ boolean hasActive = validRelease(activeRelease) && activePath.isDirectory();
32220
+ String previous = hasActive ? activePath.getAbsolutePath() : "";
32183
32221
  long started = value.optLong("pendingStartedAt", System.currentTimeMillis());
32184
32222
  long duration = Math.max(0, System.currentTimeMillis() - started);
32185
32223
  value.remove("pendingRelease");
@@ -40308,5 +40346,5 @@ export {
40308
40346
  writeAbsoluteMobileUpdateRegistry
40309
40347
  };
40310
40348
 
40311
- //# debugId=DB548297ABB3C7C964756E2164756E21
40349
+ //# debugId=D0534BA5887457BD64756E2164756E21
40312
40350
  //# sourceMappingURL=index.js.map