@hot-updater/protocol 1.0.0-rc.47 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -503,11 +503,15 @@ function selectDesiredRelease(catalog, input) {
503
503
  const activeReleaseId = input.activeReleaseId ?? null;
504
504
  const hasActiveBundle = input.currentBundleId !== input.builtInBundleId;
505
505
  const isSafeBundleRelease = (release) => release.bundleId !== null && !crashedBundleIds.has(release.bundleId) && release.bundleId >= input.minimumReleaseId;
506
+ const runningReleaseId = input.runningReleaseId === void 0 ? activeReleaseId : input.runningReleaseId;
507
+ const isNewerThanRunning = (release) => runningReleaseId !== null ? release.releaseId > runningReleaseId : release.bundleId !== null && release.bundleId > input.currentBundleId;
508
+ const passesForcedRelease = (selected) => [selected, ...catalog.rollbackReleases].some((passed) => passed.shouldForceUpdate && passed.bundleId !== null && passed.bundleId >= input.minimumReleaseId && passed.bundleId !== input.currentBundleId && passed.releaseId <= selected.releaseId && isNewerThanRunning(passed) && isReleaseEligibleForCohort(passed, input.cohort));
506
509
  const desiredBundle = (release, status) => ({
507
510
  bundleId: release.bundleId,
508
511
  kind: "BUNDLE",
509
512
  release,
510
513
  releaseId: release.releaseId,
514
+ shouldForceUpdate: status === "ROLLBACK" || passesForcedRelease(release),
511
515
  status
512
516
  });
513
517
  for (const release of catalog.releases) {
@@ -529,6 +533,7 @@ function selectDesiredRelease(catalog, input) {
529
533
  kind: "BUILTIN",
530
534
  release: null,
531
535
  releaseId: null,
536
+ shouldForceUpdate: true,
532
537
  status: "ROLLBACK"
533
538
  };
534
539
  }
package/dist/index.d.cts CHANGED
@@ -470,6 +470,12 @@ interface ReleaseSelectionInput {
470
470
  readonly builtInBundleId: string;
471
471
  readonly currentBundleId: string;
472
472
  readonly activeReleaseId?: string | null;
473
+ /**
474
+ * The Release of the bundle the app is running, which differs from
475
+ * `activeReleaseId` while a newer bundle is staged for the next launch.
476
+ * Defaults to `activeReleaseId`; null compares by `currentBundleId`.
477
+ */
478
+ readonly runningReleaseId?: string | null;
473
479
  readonly minimumReleaseId: string;
474
480
  readonly cohort: string | null | undefined;
475
481
  readonly crashedBundleIds: readonly string[];
@@ -490,6 +496,14 @@ type DesiredRelease = {
490
496
  readonly bundleId: string;
491
497
  readonly release: ReleaseCatalogDescriptor | null;
492
498
  readonly status: "UPDATE" | "ROLLBACK";
499
+ /**
500
+ * Whether the device must apply this transition immediately: every rollback,
501
+ * and an update when a forced Release the device's cohort was eligible for
502
+ * lies after the running bundle's Release, up to and including the selected
503
+ * Release. Skipping past a forced Release, or staging a newer one before
504
+ * it was forced, does not drop its requirement.
505
+ */
506
+ readonly shouldForceUpdate: boolean;
493
507
  };
494
508
  declare function isReleaseEligibleForCohort(release: Pick<ReleaseCatalogDescriptor, "releaseId" | "rolloutCohortCount" | "targetCohorts">, cohort: string | null | undefined): boolean;
495
509
  declare function selectDesiredRelease(catalog: ReleaseCatalog, input: ReleaseSelectionInput): DesiredRelease | null;
package/dist/index.d.mts CHANGED
@@ -470,6 +470,12 @@ interface ReleaseSelectionInput {
470
470
  readonly builtInBundleId: string;
471
471
  readonly currentBundleId: string;
472
472
  readonly activeReleaseId?: string | null;
473
+ /**
474
+ * The Release of the bundle the app is running, which differs from
475
+ * `activeReleaseId` while a newer bundle is staged for the next launch.
476
+ * Defaults to `activeReleaseId`; null compares by `currentBundleId`.
477
+ */
478
+ readonly runningReleaseId?: string | null;
473
479
  readonly minimumReleaseId: string;
474
480
  readonly cohort: string | null | undefined;
475
481
  readonly crashedBundleIds: readonly string[];
@@ -490,6 +496,14 @@ type DesiredRelease = {
490
496
  readonly bundleId: string;
491
497
  readonly release: ReleaseCatalogDescriptor | null;
492
498
  readonly status: "UPDATE" | "ROLLBACK";
499
+ /**
500
+ * Whether the device must apply this transition immediately: every rollback,
501
+ * and an update when a forced Release the device's cohort was eligible for
502
+ * lies after the running bundle's Release, up to and including the selected
503
+ * Release. Skipping past a forced Release, or staging a newer one before
504
+ * it was forced, does not drop its requirement.
505
+ */
506
+ readonly shouldForceUpdate: boolean;
493
507
  };
494
508
  declare function isReleaseEligibleForCohort(release: Pick<ReleaseCatalogDescriptor, "releaseId" | "rolloutCohortCount" | "targetCohorts">, cohort: string | null | undefined): boolean;
495
509
  declare function selectDesiredRelease(catalog: ReleaseCatalog, input: ReleaseSelectionInput): DesiredRelease | null;
package/dist/index.mjs CHANGED
@@ -502,11 +502,15 @@ function selectDesiredRelease(catalog, input) {
502
502
  const activeReleaseId = input.activeReleaseId ?? null;
503
503
  const hasActiveBundle = input.currentBundleId !== input.builtInBundleId;
504
504
  const isSafeBundleRelease = (release) => release.bundleId !== null && !crashedBundleIds.has(release.bundleId) && release.bundleId >= input.minimumReleaseId;
505
+ const runningReleaseId = input.runningReleaseId === void 0 ? activeReleaseId : input.runningReleaseId;
506
+ const isNewerThanRunning = (release) => runningReleaseId !== null ? release.releaseId > runningReleaseId : release.bundleId !== null && release.bundleId > input.currentBundleId;
507
+ const passesForcedRelease = (selected) => [selected, ...catalog.rollbackReleases].some((passed) => passed.shouldForceUpdate && passed.bundleId !== null && passed.bundleId >= input.minimumReleaseId && passed.bundleId !== input.currentBundleId && passed.releaseId <= selected.releaseId && isNewerThanRunning(passed) && isReleaseEligibleForCohort(passed, input.cohort));
505
508
  const desiredBundle = (release, status) => ({
506
509
  bundleId: release.bundleId,
507
510
  kind: "BUNDLE",
508
511
  release,
509
512
  releaseId: release.releaseId,
513
+ shouldForceUpdate: status === "ROLLBACK" || passesForcedRelease(release),
510
514
  status
511
515
  });
512
516
  for (const release of catalog.releases) {
@@ -528,6 +532,7 @@ function selectDesiredRelease(catalog, input) {
528
532
  kind: "BUILTIN",
529
533
  release: null,
530
534
  releaseId: null,
535
+ shouldForceUpdate: true,
531
536
  status: "ROLLBACK"
532
537
  };
533
538
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hot-updater/protocol",
3
- "version": "1.0.0-rc.47",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "description": "The data formats and pure computations that Hot Updater's app and server share",
6
6
  "sideEffects": false,