@hot-updater/core 0.30.11 → 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 +44 -0
- package/dist/index.d.cts +113 -18
- package/dist/index.d.mts +113 -18
- package/dist/index.mjs +35 -1
- package/package.json +1 -1
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
|
|
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
|
|
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 };
|