@hot-updater/core 0.30.12 → 0.31.0

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
@@ -1,4 +1,38 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/bundleArtifacts.ts
3
+ const stripBundleArtifactMetadata = (metadata) => metadata;
4
+ const getManifestStorageUri = (bundle) => bundle.manifestStorageUri ?? null;
5
+ const getManifestFileHash = (bundle) => bundle.manifestFileHash ?? null;
6
+ const getAssetBaseStorageUri = (bundle) => bundle.assetBaseStorageUri ?? null;
7
+ const isBundlePatchArtifact = (value) => {
8
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
9
+ const candidate = value;
10
+ return typeof candidate.baseBundleId === "string" && typeof candidate.baseFileHash === "string" && typeof candidate.patchFileHash === "string" && typeof candidate.patchStorageUri === "string";
11
+ };
12
+ const readBundlePatchArray = (patches) => {
13
+ if (!Array.isArray(patches)) return [];
14
+ return patches.filter(isBundlePatchArtifact);
15
+ };
16
+ const getBundlePatches = (bundle) => {
17
+ const patches = readBundlePatchArray(bundle.patches);
18
+ const seenBaseBundleIds = /* @__PURE__ */ new Set();
19
+ return patches.filter((patch) => {
20
+ if (seenBaseBundleIds.has(patch.baseBundleId)) return false;
21
+ seenBaseBundleIds.add(patch.baseBundleId);
22
+ return true;
23
+ });
24
+ };
25
+ const getBundlePatch = (bundle, baseBundleId) => {
26
+ return getBundlePatches(bundle).find((patch) => patch.baseBundleId === baseBundleId) ?? null;
27
+ };
28
+ const getPrimaryPatch = (bundle) => {
29
+ return getBundlePatches(bundle)[0] ?? null;
30
+ };
31
+ const getPatchBaseBundleId = (bundle) => bundle.patchBaseBundleId ?? getPrimaryPatch(bundle)?.baseBundleId ?? null;
32
+ const getPatchBaseFileHash = (bundle) => bundle.patchBaseFileHash ?? getPrimaryPatch(bundle)?.baseFileHash ?? null;
33
+ const getPatchFileHash = (bundle) => bundle.patchFileHash ?? getPrimaryPatch(bundle)?.patchFileHash ?? null;
34
+ const getPatchStorageUri = (bundle) => bundle.patchStorageUri ?? getPrimaryPatch(bundle)?.patchStorageUri ?? null;
35
+ //#endregion
2
36
  //#region src/rollout.ts
3
37
  const NUMERIC_COHORT_SIZE = 1e3;
4
38
  const DEFAULT_ROLLOUT_COHORT_COUNT = NUMERIC_COHORT_SIZE;
@@ -124,9 +158,18 @@ exports.INVALID_COHORT_ERROR_MESSAGE = INVALID_COHORT_ERROR_MESSAGE;
124
158
  exports.MAX_COHORT_LENGTH = MAX_COHORT_LENGTH;
125
159
  exports.NIL_UUID = NIL_UUID;
126
160
  exports.NUMERIC_COHORT_SIZE = NUMERIC_COHORT_SIZE;
161
+ exports.getAssetBaseStorageUri = getAssetBaseStorageUri;
162
+ exports.getBundlePatch = getBundlePatch;
163
+ exports.getBundlePatches = getBundlePatches;
127
164
  exports.getDefaultNumericCohort = getDefaultNumericCohort;
165
+ exports.getManifestFileHash = getManifestFileHash;
166
+ exports.getManifestStorageUri = getManifestStorageUri;
128
167
  exports.getNumericCohortRolloutPosition = getNumericCohortRolloutPosition;
129
168
  exports.getNumericCohortValue = getNumericCohortValue;
169
+ exports.getPatchBaseBundleId = getPatchBaseBundleId;
170
+ exports.getPatchBaseFileHash = getPatchBaseFileHash;
171
+ exports.getPatchFileHash = getPatchFileHash;
172
+ exports.getPatchStorageUri = getPatchStorageUri;
130
173
  exports.getRolledOutNumericCohorts = getRolledOutNumericCohorts;
131
174
  exports.isCohortEligibleForUpdate = isCohortEligibleForUpdate;
132
175
  exports.isCustomCohort = isCustomCohort;
@@ -134,3 +177,4 @@ exports.isNumericCohort = isNumericCohort;
134
177
  exports.isValidCohort = isValidCohort;
135
178
  exports.normalizeCohortValue = normalizeCohortValue;
136
179
  exports.normalizeRolloutCohortCount = normalizeRolloutCohortCount;
180
+ exports.stripBundleArtifactMetadata = stripBundleArtifactMetadata;
package/dist/index.d.cts CHANGED
@@ -1,24 +1,30 @@
1
- //#region src/rollout.d.ts
2
- declare const NUMERIC_COHORT_SIZE = 1000;
3
- declare const DEFAULT_ROLLOUT_COHORT_COUNT = 1000;
4
- declare const MAX_COHORT_LENGTH = 64;
5
- declare const INVALID_COHORT_ERROR_MESSAGE = "Invalid cohort. Use 1-1000 or a lowercase slug without spaces, up to 64 characters.";
6
- declare function normalizeRolloutCohortCount(rolloutCohortCount: number | null | undefined): number;
7
- declare function normalizeCohortValue(cohort: string): string;
8
- declare function getNumericCohortValue(cohort: string): number | null;
9
- declare function isNumericCohort(cohort: string): boolean;
10
- declare function isCustomCohort(cohort: string): boolean;
11
- declare function isValidCohort(cohort: string): boolean;
12
- declare function getDefaultNumericCohort(identifier: string): string;
13
- declare function getNumericCohortRolloutPosition(bundleId: string, cohortValue: number): number;
14
- declare function getRolledOutNumericCohorts(bundleId: string, rolloutCohortCount: number | null | undefined): number[];
15
- declare function isCohortEligibleForUpdate(bundleId: string, cohort: string | null | undefined, rolloutCohortCount: number | null | undefined, targetCohorts: readonly string[] | null | undefined): boolean;
16
- //#endregion
17
1
  //#region src/types.d.ts
18
2
  type Platform = "ios" | "android";
19
3
  type BundleMetadata = {
20
4
  app_version?: string;
21
5
  };
6
+ interface BundlePatchArtifact {
7
+ baseBundleId: string;
8
+ baseFileHash: string;
9
+ patchFileHash: string;
10
+ patchStorageUri: string;
11
+ }
12
+ interface ChangedAssetPatch {
13
+ algorithm: "bsdiff";
14
+ baseBundleId: string;
15
+ baseFileHash: string;
16
+ patchFileHash: string;
17
+ patchUrl: string;
18
+ }
19
+ interface ChangedAssetFile {
20
+ compression?: "br" | null;
21
+ url: string;
22
+ }
23
+ interface ChangedAsset {
24
+ file?: ChangedAssetFile | null;
25
+ fileHash: string;
26
+ patch?: ChangedAssetPatch | null;
27
+ }
22
28
  interface Bundle {
23
29
  /**
24
30
  * The unique identifier for the bundle. uuidv7
@@ -80,6 +86,43 @@ interface Bundle {
80
86
  * The metadata of the bundle.
81
87
  */
82
88
  metadata?: BundleMetadata;
89
+ /**
90
+ * Storage URI for the bundle manifest artifact.
91
+ */
92
+ manifestStorageUri?: string | null;
93
+ /**
94
+ * SHA256 hash of the manifest artifact, optionally signed as sig:<signature>.
95
+ */
96
+ manifestFileHash?: string | null;
97
+ /**
98
+ * Storage URI prefix for manifest assets.
99
+ */
100
+ assetBaseStorageUri?: string | null;
101
+ /**
102
+ * Binary patch artifacts keyed by base bundle in array order.
103
+ * Earlier entries take precedence when a single "primary" patch is needed.
104
+ */
105
+ patches?: BundlePatchArtifact[] | null;
106
+ /**
107
+ * Base bundle id used to generate this bundle's binary patch.
108
+ * @deprecated Use Bundle.patches.
109
+ */
110
+ patchBaseBundleId?: string | null;
111
+ /**
112
+ * Expected hash of the base asset before patch application.
113
+ * @deprecated Use Bundle.patches.
114
+ */
115
+ patchBaseFileHash?: string | null;
116
+ /**
117
+ * Expected hash of the binary patch artifact.
118
+ * @deprecated Use Bundle.patches.
119
+ */
120
+ patchFileHash?: string | null;
121
+ /**
122
+ * Storage URI for the binary patch artifact.
123
+ * @deprecated Use Bundle.patches.
124
+ */
125
+ patchStorageUri?: string | null;
83
126
  /**
84
127
  * Rollout cohort count (0-1000). Controls gradual rollout to numeric cohorts.
85
128
  * - 0: No cohorts receive this update
@@ -105,6 +148,7 @@ type SnakeCase<S extends string> = S extends `${infer T}${infer U}` ? T extends
105
148
  type SnakeKeyObject<T> = T extends readonly (infer U)[] ? SnakeKeyObject<U>[] : T extends Record<string, any> ? { [K in keyof T as SnakeCase<Extract<K, string>>]: SnakeKeyObject<T[K]> } : T;
106
149
  type SnakeCaseBundle = SnakeKeyObject<Bundle>;
107
150
  type UpdateStatus = "ROLLBACK" | "UPDATE";
151
+ type AppUpdateStatus = UpdateStatus | "UP_TO_DATE";
108
152
  /**
109
153
  * The update info for the database layer.
110
154
  * This is the update info that is used by the database.
@@ -130,7 +174,8 @@ interface UpdateInfo {
130
174
  * The update info for the app layer.
131
175
  * This is the update info that is used by the app.
132
176
  */
133
- interface AppUpdateInfo extends Omit<UpdateInfo, "storageUri"> {
177
+ interface AppUpdateAvailableInfo extends Omit<UpdateInfo, "storageUri"> {
178
+ status: UpdateStatus;
134
179
  fileUrl: string | null;
135
180
  /**
136
181
  * SHA256 hash of the bundle file, optionally with embedded signature.
@@ -139,7 +184,29 @@ interface AppUpdateInfo extends Omit<UpdateInfo, "storageUri"> {
139
184
  * The client parses this to extract signature for native verification.
140
185
  */
141
186
  fileHash: string | null;
187
+ /**
188
+ * Optional manifest artifact for manifest-driven updates.
189
+ * When present with `changedAssets`, native can download and verify a signed
190
+ * manifest, then assemble the next bundle directory from reused and changed
191
+ * files while keeping archive fallback available through `fileUrl`.
192
+ */
193
+ manifestUrl?: string | null;
194
+ /**
195
+ * SHA256 hash of the manifest file, optionally with embedded signature.
196
+ * Follows the same `sig:<base64_signature>` or plain hex format as `fileHash`.
197
+ */
198
+ manifestFileHash?: string | null;
199
+ /**
200
+ * Per-file descriptors for assets whose hash differs from the client's
201
+ * current manifest, or for all assets when the server cannot reuse a base
202
+ * manifest. Keys are manifest-relative file paths.
203
+ */
204
+ changedAssets?: Record<string, ChangedAsset> | null;
205
+ }
206
+ interface AppUpToDateInfo {
207
+ status: "UP_TO_DATE";
142
208
  }
209
+ type AppUpdateInfo = AppUpdateAvailableInfo | AppUpToDateInfo;
143
210
  type UpdateStrategy = "fingerprint" | "appVersion";
144
211
  type FingerprintGetBundlesArgs = {
145
212
  _updateStrategy: "fingerprint";
@@ -221,7 +288,35 @@ type UpdateBundleParams = {
221
288
  fingerprintHash: string | null;
222
289
  };
223
290
  //#endregion
291
+ //#region src/bundleArtifacts.d.ts
292
+ declare const stripBundleArtifactMetadata: (metadata: BundleMetadata | undefined) => BundleMetadata | undefined;
293
+ declare const getManifestStorageUri: (bundle: Pick<Bundle, "manifestStorageUri" | "metadata">) => string | null;
294
+ declare const getManifestFileHash: (bundle: Pick<Bundle, "manifestFileHash" | "metadata">) => string | null;
295
+ declare const getAssetBaseStorageUri: (bundle: Pick<Bundle, "assetBaseStorageUri" | "metadata">) => string | null;
296
+ declare const getBundlePatches: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">) => BundlePatchArtifact[];
297
+ declare const getBundlePatch: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">, baseBundleId: string) => BundlePatchArtifact | null;
298
+ declare const getPatchBaseBundleId: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">) => string;
299
+ declare const getPatchBaseFileHash: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">) => string;
300
+ declare const getPatchFileHash: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">) => string;
301
+ declare const getPatchStorageUri: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">) => string;
302
+ //#endregion
303
+ //#region src/rollout.d.ts
304
+ declare const NUMERIC_COHORT_SIZE = 1000;
305
+ declare const DEFAULT_ROLLOUT_COHORT_COUNT = 1000;
306
+ declare const MAX_COHORT_LENGTH = 64;
307
+ declare const INVALID_COHORT_ERROR_MESSAGE = "Invalid cohort. Use 1-1000 or a lowercase slug without spaces, up to 64 characters.";
308
+ declare function normalizeRolloutCohortCount(rolloutCohortCount: number | null | undefined): number;
309
+ declare function normalizeCohortValue(cohort: string): string;
310
+ declare function getNumericCohortValue(cohort: string): number | null;
311
+ declare function isNumericCohort(cohort: string): boolean;
312
+ declare function isCustomCohort(cohort: string): boolean;
313
+ declare function isValidCohort(cohort: string): boolean;
314
+ declare function getDefaultNumericCohort(identifier: string): string;
315
+ declare function getNumericCohortRolloutPosition(bundleId: string, cohortValue: number): number;
316
+ declare function getRolledOutNumericCohorts(bundleId: string, rolloutCohortCount: number | null | undefined): number[];
317
+ declare function isCohortEligibleForUpdate(bundleId: string, cohort: string | null | undefined, rolloutCohortCount: number | null | undefined, targetCohorts: readonly string[] | null | undefined): boolean;
318
+ //#endregion
224
319
  //#region src/uuid.d.ts
225
320
  declare const NIL_UUID = "00000000-0000-0000-0000-000000000000";
226
321
  //#endregion
227
- export { AppUpdateInfo, AppVersionGetBundlesArgs, Bundle, BundleMetadata, DEFAULT_ROLLOUT_COHORT_COUNT, FingerprintGetBundlesArgs, GetBundlesArgs, INVALID_COHORT_ERROR_MESSAGE, MAX_COHORT_LENGTH, NIL_UUID, NUMERIC_COHORT_SIZE, Platform, SnakeCaseBundle, UpdateBundleParams, UpdateInfo, UpdateStatus, UpdateStrategy, getDefaultNumericCohort, getNumericCohortRolloutPosition, getNumericCohortValue, getRolledOutNumericCohorts, isCohortEligibleForUpdate, isCustomCohort, isNumericCohort, isValidCohort, normalizeCohortValue, normalizeRolloutCohortCount };
322
+ export { AppUpToDateInfo, AppUpdateAvailableInfo, AppUpdateInfo, AppUpdateStatus, AppVersionGetBundlesArgs, Bundle, BundleMetadata, BundlePatchArtifact, ChangedAsset, ChangedAssetFile, ChangedAssetPatch, DEFAULT_ROLLOUT_COHORT_COUNT, FingerprintGetBundlesArgs, GetBundlesArgs, INVALID_COHORT_ERROR_MESSAGE, MAX_COHORT_LENGTH, NIL_UUID, NUMERIC_COHORT_SIZE, Platform, SnakeCaseBundle, UpdateBundleParams, UpdateInfo, UpdateStatus, UpdateStrategy, getAssetBaseStorageUri, getBundlePatch, getBundlePatches, getDefaultNumericCohort, getManifestFileHash, getManifestStorageUri, getNumericCohortRolloutPosition, getNumericCohortValue, getPatchBaseBundleId, getPatchBaseFileHash, getPatchFileHash, getPatchStorageUri, getRolledOutNumericCohorts, isCohortEligibleForUpdate, isCustomCohort, isNumericCohort, isValidCohort, normalizeCohortValue, normalizeRolloutCohortCount, stripBundleArtifactMetadata };
package/dist/index.d.mts CHANGED
@@ -1,24 +1,30 @@
1
- //#region src/rollout.d.ts
2
- declare const NUMERIC_COHORT_SIZE = 1000;
3
- declare const DEFAULT_ROLLOUT_COHORT_COUNT = 1000;
4
- declare const MAX_COHORT_LENGTH = 64;
5
- declare const INVALID_COHORT_ERROR_MESSAGE = "Invalid cohort. Use 1-1000 or a lowercase slug without spaces, up to 64 characters.";
6
- declare function normalizeRolloutCohortCount(rolloutCohortCount: number | null | undefined): number;
7
- declare function normalizeCohortValue(cohort: string): string;
8
- declare function getNumericCohortValue(cohort: string): number | null;
9
- declare function isNumericCohort(cohort: string): boolean;
10
- declare function isCustomCohort(cohort: string): boolean;
11
- declare function isValidCohort(cohort: string): boolean;
12
- declare function getDefaultNumericCohort(identifier: string): string;
13
- declare function getNumericCohortRolloutPosition(bundleId: string, cohortValue: number): number;
14
- declare function getRolledOutNumericCohorts(bundleId: string, rolloutCohortCount: number | null | undefined): number[];
15
- declare function isCohortEligibleForUpdate(bundleId: string, cohort: string | null | undefined, rolloutCohortCount: number | null | undefined, targetCohorts: readonly string[] | null | undefined): boolean;
16
- //#endregion
17
1
  //#region src/types.d.ts
18
2
  type Platform = "ios" | "android";
19
3
  type BundleMetadata = {
20
4
  app_version?: string;
21
5
  };
6
+ interface BundlePatchArtifact {
7
+ baseBundleId: string;
8
+ baseFileHash: string;
9
+ patchFileHash: string;
10
+ patchStorageUri: string;
11
+ }
12
+ interface ChangedAssetPatch {
13
+ algorithm: "bsdiff";
14
+ baseBundleId: string;
15
+ baseFileHash: string;
16
+ patchFileHash: string;
17
+ patchUrl: string;
18
+ }
19
+ interface ChangedAssetFile {
20
+ compression?: "br" | null;
21
+ url: string;
22
+ }
23
+ interface ChangedAsset {
24
+ file?: ChangedAssetFile | null;
25
+ fileHash: string;
26
+ patch?: ChangedAssetPatch | null;
27
+ }
22
28
  interface Bundle {
23
29
  /**
24
30
  * The unique identifier for the bundle. uuidv7
@@ -80,6 +86,43 @@ interface Bundle {
80
86
  * The metadata of the bundle.
81
87
  */
82
88
  metadata?: BundleMetadata;
89
+ /**
90
+ * Storage URI for the bundle manifest artifact.
91
+ */
92
+ manifestStorageUri?: string | null;
93
+ /**
94
+ * SHA256 hash of the manifest artifact, optionally signed as sig:<signature>.
95
+ */
96
+ manifestFileHash?: string | null;
97
+ /**
98
+ * Storage URI prefix for manifest assets.
99
+ */
100
+ assetBaseStorageUri?: string | null;
101
+ /**
102
+ * Binary patch artifacts keyed by base bundle in array order.
103
+ * Earlier entries take precedence when a single "primary" patch is needed.
104
+ */
105
+ patches?: BundlePatchArtifact[] | null;
106
+ /**
107
+ * Base bundle id used to generate this bundle's binary patch.
108
+ * @deprecated Use Bundle.patches.
109
+ */
110
+ patchBaseBundleId?: string | null;
111
+ /**
112
+ * Expected hash of the base asset before patch application.
113
+ * @deprecated Use Bundle.patches.
114
+ */
115
+ patchBaseFileHash?: string | null;
116
+ /**
117
+ * Expected hash of the binary patch artifact.
118
+ * @deprecated Use Bundle.patches.
119
+ */
120
+ patchFileHash?: string | null;
121
+ /**
122
+ * Storage URI for the binary patch artifact.
123
+ * @deprecated Use Bundle.patches.
124
+ */
125
+ patchStorageUri?: string | null;
83
126
  /**
84
127
  * Rollout cohort count (0-1000). Controls gradual rollout to numeric cohorts.
85
128
  * - 0: No cohorts receive this update
@@ -105,6 +148,7 @@ type SnakeCase<S extends string> = S extends `${infer T}${infer U}` ? T extends
105
148
  type SnakeKeyObject<T> = T extends readonly (infer U)[] ? SnakeKeyObject<U>[] : T extends Record<string, any> ? { [K in keyof T as SnakeCase<Extract<K, string>>]: SnakeKeyObject<T[K]> } : T;
106
149
  type SnakeCaseBundle = SnakeKeyObject<Bundle>;
107
150
  type UpdateStatus = "ROLLBACK" | "UPDATE";
151
+ type AppUpdateStatus = UpdateStatus | "UP_TO_DATE";
108
152
  /**
109
153
  * The update info for the database layer.
110
154
  * This is the update info that is used by the database.
@@ -130,7 +174,8 @@ interface UpdateInfo {
130
174
  * The update info for the app layer.
131
175
  * This is the update info that is used by the app.
132
176
  */
133
- interface AppUpdateInfo extends Omit<UpdateInfo, "storageUri"> {
177
+ interface AppUpdateAvailableInfo extends Omit<UpdateInfo, "storageUri"> {
178
+ status: UpdateStatus;
134
179
  fileUrl: string | null;
135
180
  /**
136
181
  * SHA256 hash of the bundle file, optionally with embedded signature.
@@ -139,7 +184,29 @@ interface AppUpdateInfo extends Omit<UpdateInfo, "storageUri"> {
139
184
  * The client parses this to extract signature for native verification.
140
185
  */
141
186
  fileHash: string | null;
187
+ /**
188
+ * Optional manifest artifact for manifest-driven updates.
189
+ * When present with `changedAssets`, native can download and verify a signed
190
+ * manifest, then assemble the next bundle directory from reused and changed
191
+ * files while keeping archive fallback available through `fileUrl`.
192
+ */
193
+ manifestUrl?: string | null;
194
+ /**
195
+ * SHA256 hash of the manifest file, optionally with embedded signature.
196
+ * Follows the same `sig:<base64_signature>` or plain hex format as `fileHash`.
197
+ */
198
+ manifestFileHash?: string | null;
199
+ /**
200
+ * Per-file descriptors for assets whose hash differs from the client's
201
+ * current manifest, or for all assets when the server cannot reuse a base
202
+ * manifest. Keys are manifest-relative file paths.
203
+ */
204
+ changedAssets?: Record<string, ChangedAsset> | null;
205
+ }
206
+ interface AppUpToDateInfo {
207
+ status: "UP_TO_DATE";
142
208
  }
209
+ type AppUpdateInfo = AppUpdateAvailableInfo | AppUpToDateInfo;
143
210
  type UpdateStrategy = "fingerprint" | "appVersion";
144
211
  type FingerprintGetBundlesArgs = {
145
212
  _updateStrategy: "fingerprint";
@@ -221,7 +288,35 @@ type UpdateBundleParams = {
221
288
  fingerprintHash: string | null;
222
289
  };
223
290
  //#endregion
291
+ //#region src/bundleArtifacts.d.ts
292
+ declare const stripBundleArtifactMetadata: (metadata: BundleMetadata | undefined) => BundleMetadata | undefined;
293
+ declare const getManifestStorageUri: (bundle: Pick<Bundle, "manifestStorageUri" | "metadata">) => string | null;
294
+ declare const getManifestFileHash: (bundle: Pick<Bundle, "manifestFileHash" | "metadata">) => string | null;
295
+ declare const getAssetBaseStorageUri: (bundle: Pick<Bundle, "assetBaseStorageUri" | "metadata">) => string | null;
296
+ declare const getBundlePatches: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">) => BundlePatchArtifact[];
297
+ declare const getBundlePatch: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">, baseBundleId: string) => BundlePatchArtifact | null;
298
+ declare const getPatchBaseBundleId: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">) => string;
299
+ declare const getPatchBaseFileHash: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">) => string;
300
+ declare const getPatchFileHash: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">) => string;
301
+ declare const getPatchStorageUri: (bundle: Pick<Bundle, "patches" | "patchBaseBundleId" | "patchBaseFileHash" | "patchFileHash" | "patchStorageUri" | "metadata">) => string;
302
+ //#endregion
303
+ //#region src/rollout.d.ts
304
+ declare const NUMERIC_COHORT_SIZE = 1000;
305
+ declare const DEFAULT_ROLLOUT_COHORT_COUNT = 1000;
306
+ declare const MAX_COHORT_LENGTH = 64;
307
+ declare const INVALID_COHORT_ERROR_MESSAGE = "Invalid cohort. Use 1-1000 or a lowercase slug without spaces, up to 64 characters.";
308
+ declare function normalizeRolloutCohortCount(rolloutCohortCount: number | null | undefined): number;
309
+ declare function normalizeCohortValue(cohort: string): string;
310
+ declare function getNumericCohortValue(cohort: string): number | null;
311
+ declare function isNumericCohort(cohort: string): boolean;
312
+ declare function isCustomCohort(cohort: string): boolean;
313
+ declare function isValidCohort(cohort: string): boolean;
314
+ declare function getDefaultNumericCohort(identifier: string): string;
315
+ declare function getNumericCohortRolloutPosition(bundleId: string, cohortValue: number): number;
316
+ declare function getRolledOutNumericCohorts(bundleId: string, rolloutCohortCount: number | null | undefined): number[];
317
+ declare function isCohortEligibleForUpdate(bundleId: string, cohort: string | null | undefined, rolloutCohortCount: number | null | undefined, targetCohorts: readonly string[] | null | undefined): boolean;
318
+ //#endregion
224
319
  //#region src/uuid.d.ts
225
320
  declare const NIL_UUID = "00000000-0000-0000-0000-000000000000";
226
321
  //#endregion
227
- export { AppUpdateInfo, AppVersionGetBundlesArgs, Bundle, BundleMetadata, DEFAULT_ROLLOUT_COHORT_COUNT, FingerprintGetBundlesArgs, GetBundlesArgs, INVALID_COHORT_ERROR_MESSAGE, MAX_COHORT_LENGTH, NIL_UUID, NUMERIC_COHORT_SIZE, Platform, SnakeCaseBundle, UpdateBundleParams, UpdateInfo, UpdateStatus, UpdateStrategy, getDefaultNumericCohort, getNumericCohortRolloutPosition, getNumericCohortValue, getRolledOutNumericCohorts, isCohortEligibleForUpdate, isCustomCohort, isNumericCohort, isValidCohort, normalizeCohortValue, normalizeRolloutCohortCount };
322
+ export { AppUpToDateInfo, AppUpdateAvailableInfo, AppUpdateInfo, AppUpdateStatus, AppVersionGetBundlesArgs, Bundle, BundleMetadata, BundlePatchArtifact, ChangedAsset, ChangedAssetFile, ChangedAssetPatch, DEFAULT_ROLLOUT_COHORT_COUNT, FingerprintGetBundlesArgs, GetBundlesArgs, INVALID_COHORT_ERROR_MESSAGE, MAX_COHORT_LENGTH, NIL_UUID, NUMERIC_COHORT_SIZE, Platform, SnakeCaseBundle, UpdateBundleParams, UpdateInfo, UpdateStatus, UpdateStrategy, getAssetBaseStorageUri, getBundlePatch, getBundlePatches, getDefaultNumericCohort, getManifestFileHash, getManifestStorageUri, getNumericCohortRolloutPosition, getNumericCohortValue, getPatchBaseBundleId, getPatchBaseFileHash, getPatchFileHash, getPatchStorageUri, getRolledOutNumericCohorts, isCohortEligibleForUpdate, isCustomCohort, isNumericCohort, isValidCohort, normalizeCohortValue, normalizeRolloutCohortCount, stripBundleArtifactMetadata };
package/dist/index.mjs CHANGED
@@ -1,3 +1,37 @@
1
+ //#region src/bundleArtifacts.ts
2
+ const stripBundleArtifactMetadata = (metadata) => metadata;
3
+ const getManifestStorageUri = (bundle) => bundle.manifestStorageUri ?? null;
4
+ const getManifestFileHash = (bundle) => bundle.manifestFileHash ?? null;
5
+ const getAssetBaseStorageUri = (bundle) => bundle.assetBaseStorageUri ?? null;
6
+ const isBundlePatchArtifact = (value) => {
7
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
8
+ const candidate = value;
9
+ return typeof candidate.baseBundleId === "string" && typeof candidate.baseFileHash === "string" && typeof candidate.patchFileHash === "string" && typeof candidate.patchStorageUri === "string";
10
+ };
11
+ const readBundlePatchArray = (patches) => {
12
+ if (!Array.isArray(patches)) return [];
13
+ return patches.filter(isBundlePatchArtifact);
14
+ };
15
+ const getBundlePatches = (bundle) => {
16
+ const patches = readBundlePatchArray(bundle.patches);
17
+ const seenBaseBundleIds = /* @__PURE__ */ new Set();
18
+ return patches.filter((patch) => {
19
+ if (seenBaseBundleIds.has(patch.baseBundleId)) return false;
20
+ seenBaseBundleIds.add(patch.baseBundleId);
21
+ return true;
22
+ });
23
+ };
24
+ const getBundlePatch = (bundle, baseBundleId) => {
25
+ return getBundlePatches(bundle).find((patch) => patch.baseBundleId === baseBundleId) ?? null;
26
+ };
27
+ const getPrimaryPatch = (bundle) => {
28
+ return getBundlePatches(bundle)[0] ?? null;
29
+ };
30
+ const getPatchBaseBundleId = (bundle) => bundle.patchBaseBundleId ?? getPrimaryPatch(bundle)?.baseBundleId ?? null;
31
+ const getPatchBaseFileHash = (bundle) => bundle.patchBaseFileHash ?? getPrimaryPatch(bundle)?.baseFileHash ?? null;
32
+ const getPatchFileHash = (bundle) => bundle.patchFileHash ?? getPrimaryPatch(bundle)?.patchFileHash ?? null;
33
+ const getPatchStorageUri = (bundle) => bundle.patchStorageUri ?? getPrimaryPatch(bundle)?.patchStorageUri ?? null;
34
+ //#endregion
1
35
  //#region src/rollout.ts
2
36
  const NUMERIC_COHORT_SIZE = 1e3;
3
37
  const DEFAULT_ROLLOUT_COHORT_COUNT = NUMERIC_COHORT_SIZE;
@@ -118,4 +152,4 @@ function isCohortEligibleForUpdate(bundleId, cohort, rolloutCohortCount, targetC
118
152
  //#region src/uuid.ts
119
153
  const NIL_UUID = "00000000-0000-0000-0000-000000000000";
120
154
  //#endregion
121
- export { DEFAULT_ROLLOUT_COHORT_COUNT, INVALID_COHORT_ERROR_MESSAGE, MAX_COHORT_LENGTH, NIL_UUID, NUMERIC_COHORT_SIZE, getDefaultNumericCohort, getNumericCohortRolloutPosition, getNumericCohortValue, getRolledOutNumericCohorts, isCohortEligibleForUpdate, isCustomCohort, isNumericCohort, isValidCohort, normalizeCohortValue, normalizeRolloutCohortCount };
155
+ export { DEFAULT_ROLLOUT_COHORT_COUNT, INVALID_COHORT_ERROR_MESSAGE, MAX_COHORT_LENGTH, NIL_UUID, NUMERIC_COHORT_SIZE, getAssetBaseStorageUri, getBundlePatch, getBundlePatches, getDefaultNumericCohort, getManifestFileHash, getManifestStorageUri, getNumericCohortRolloutPosition, getNumericCohortValue, getPatchBaseBundleId, getPatchBaseFileHash, getPatchFileHash, getPatchStorageUri, getRolledOutNumericCohorts, isCohortEligibleForUpdate, isCustomCohort, isNumericCohort, isValidCohort, normalizeCohortValue, normalizeRolloutCohortCount, stripBundleArtifactMetadata };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hot-updater/core",
3
- "version": "0.30.12",
3
+ "version": "0.31.0",
4
4
  "type": "module",
5
5
  "description": "React Native OTA solution for self-hosted",
6
6
  "sideEffects": false,