@hot-updater/server 0.36.7 → 1.0.0-rc.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/adapters/databaseConstraintErrors.cjs +23 -0
- package/dist/adapters/databaseConstraintErrors.mjs +21 -0
- package/dist/adapters/databasePluginUtils.cjs +117 -0
- package/dist/adapters/databasePluginUtils.mjs +106 -0
- package/dist/adapters/drizzle.cjs +53 -176
- package/dist/adapters/drizzle.d.cts +6 -4
- package/dist/adapters/drizzle.d.mts +6 -4
- package/dist/adapters/drizzle.mjs +54 -177
- package/dist/adapters/drizzleCrud.cjs +250 -0
- package/dist/adapters/drizzleCrud.mjs +249 -0
- package/dist/adapters/drizzleLazyDB.cjs +84 -36
- package/dist/adapters/drizzleLazyDB.mjs +84 -36
- package/dist/adapters/drizzleQuery.cjs +68 -0
- package/dist/adapters/drizzleQuery.mjs +67 -0
- package/dist/adapters/kysely.cjs +18 -138
- package/dist/adapters/kysely.d.cts +3 -12
- package/dist/adapters/kysely.d.mts +3 -12
- package/dist/adapters/kysely.mjs +19 -139
- package/dist/adapters/kyselyCrud.cjs +254 -0
- package/dist/adapters/kyselyCrud.mjs +253 -0
- package/dist/adapters/kyselyQuery.cjs +56 -0
- package/dist/adapters/kyselyQuery.mjs +55 -0
- package/dist/adapters/mongodb.cjs +21 -174
- package/dist/adapters/mongodb.d.cts +3 -2
- package/dist/adapters/mongodb.d.mts +3 -2
- package/dist/adapters/mongodb.mjs +21 -174
- package/dist/adapters/mongodbCollections.cjs +36 -0
- package/dist/adapters/mongodbCollections.mjs +30 -0
- package/dist/adapters/mongodbQuery.cjs +77 -0
- package/dist/adapters/mongodbQuery.mjs +70 -0
- package/dist/adapters/mongodbReads.cjs +148 -0
- package/dist/adapters/mongodbReads.mjs +147 -0
- package/dist/adapters/mongodbWrites.cjs +134 -0
- package/dist/adapters/mongodbWrites.mjs +133 -0
- package/dist/adapters/prisma.cjs +205 -180
- package/dist/adapters/prisma.d.cts +3 -3
- package/dist/adapters/prisma.d.mts +3 -3
- package/dist/adapters/prisma.mjs +206 -181
- package/dist/adapters/prismaQuery.cjs +58 -0
- package/dist/adapters/prismaQuery.mjs +56 -0
- package/dist/adapters/prismaRows.cjs +198 -0
- package/dist/adapters/prismaRows.mjs +188 -0
- package/dist/analytics/bounded/activeOverview.cjs +87 -0
- package/dist/analytics/bounded/activeOverview.mjs +85 -0
- package/dist/analytics/bounded/installationSearch.cjs +42 -0
- package/dist/analytics/bounded/installationSearch.mjs +42 -0
- package/dist/analytics/bounded/persistence.cjs +39 -0
- package/dist/analytics/bounded/persistence.mjs +38 -0
- package/dist/analytics/bounded/provider.cjs +170 -0
- package/dist/analytics/bounded/provider.d.cts +7 -0
- package/dist/analytics/bounded/provider.d.mts +7 -0
- package/dist/analytics/bounded/provider.mjs +170 -0
- package/dist/analytics/bounded/scan.cjs +144 -0
- package/dist/analytics/bounded/scan.mjs +138 -0
- package/dist/analytics/domain.d.cts +121 -0
- package/dist/analytics/domain.d.mts +121 -0
- package/dist/analytics/errors.cjs +22 -0
- package/dist/analytics/errors.mjs +20 -0
- package/dist/analytics/eventInput.cjs +111 -0
- package/dist/analytics/eventInput.mjs +111 -0
- package/dist/analytics/persistence.d.cts +6 -0
- package/dist/analytics/persistence.d.mts +6 -0
- package/dist/analytics/queryInput.cjs +58 -0
- package/dist/analytics/queryInput.mjs +55 -0
- package/dist/analytics/routes.cjs +63 -0
- package/dist/analytics/routes.mjs +61 -0
- package/dist/analytics/types.d.cts +17 -0
- package/dist/analytics/types.d.mts +17 -0
- package/dist/apiKeys.cjs +139 -0
- package/dist/apiKeys.d.cts +50 -0
- package/dist/apiKeys.d.mts +50 -0
- package/dist/apiKeys.mjs +133 -0
- package/dist/createHotUpdaterCore.cjs +48 -26
- package/dist/createHotUpdaterCore.d.cts +49 -17
- package/dist/createHotUpdaterCore.d.mts +49 -17
- package/dist/createHotUpdaterCore.mjs +51 -29
- package/dist/db/createBundleDiff.cjs +45 -68
- package/dist/db/createBundleDiff.d.cts +3 -3
- package/dist/db/createBundleDiff.d.mts +3 -3
- package/dist/db/createBundleDiff.mjs +47 -68
- package/dist/db/databasePluginCore.cjs +138 -0
- package/dist/db/databasePluginCore.mjs +137 -0
- package/dist/db/fixedMigrator.cjs +36 -93
- package/dist/db/fixedMigrator.mjs +36 -93
- package/dist/db/fixedMigratorMongo.cjs +319 -0
- package/dist/db/fixedMigratorMongo.mjs +319 -0
- package/dist/db/fixedMigratorShared.cjs +23 -0
- package/dist/db/fixedMigratorShared.mjs +18 -0
- package/dist/db/mongoMigrationExecution.cjs +11 -0
- package/dist/db/mongoMigrationExecution.mjs +11 -0
- package/dist/db/releaseCatalog.cjs +66 -0
- package/dist/db/releaseCatalog.d.cts +17 -0
- package/dist/db/releaseCatalog.d.mts +17 -0
- package/dist/db/releaseCatalog.mjs +64 -0
- package/dist/db/schema/mongodb.cjs +14 -6
- package/dist/db/schema/mongodb.mjs +14 -6
- package/dist/db/schema/registry.cjs +0 -2
- package/dist/db/schema/registry.mjs +1 -2
- package/dist/db/schema/sql.cjs +31 -14
- package/dist/db/schema/sql.mjs +32 -13
- package/dist/db/schema/sqlOperations.cjs +4 -4
- package/dist/db/schema/sqlOperations.mjs +5 -5
- package/dist/db/schemaGenerators.cjs +52 -18
- package/dist/db/schemaGenerators.mjs +52 -18
- package/dist/db/schemaReadiness.cjs +4 -3
- package/dist/db/schemaReadiness.mjs +4 -3
- package/dist/db/sqlMigrationExecution.cjs +67 -0
- package/dist/db/sqlMigrationExecution.mjs +66 -0
- package/dist/db/types.cjs +2 -6
- package/dist/db/types.d.cts +60 -16
- package/dist/db/types.d.mts +60 -16
- package/dist/db/types.mjs +3 -6
- package/dist/db/updateArtifacts.cjs +114 -60
- package/dist/db/updateArtifacts.mjs +117 -62
- package/dist/handler.cjs +108 -282
- package/dist/handler.d.cts +3 -46
- package/dist/handler.d.mts +3 -46
- package/dist/handler.mjs +107 -281
- package/dist/handlerBundleRoutes.cjs +155 -0
- package/dist/handlerBundleRoutes.mjs +155 -0
- package/dist/handlerErrors.cjs +9 -0
- package/dist/handlerErrors.mjs +9 -0
- package/dist/handlerParameters.cjs +39 -0
- package/dist/handlerParameters.mjs +34 -0
- package/dist/handlerReleaseCatalogRoutes.cjs +111 -0
- package/dist/handlerReleaseCatalogRoutes.mjs +110 -0
- package/dist/handlerReleaseManagementRoutes.cjs +125 -0
- package/dist/handlerReleaseManagementRoutes.mjs +124 -0
- package/dist/handlerTypes.d.cts +63 -0
- package/dist/handlerTypes.d.mts +63 -0
- package/dist/handlerVersionRoutes.cjs +10 -0
- package/dist/handlerVersionRoutes.d.cts +4 -0
- package/dist/handlerVersionRoutes.d.mts +4 -0
- package/dist/handlerVersionRoutes.mjs +9 -0
- package/dist/index.cjs +10 -1
- package/dist/index.d.cts +9 -3
- package/dist/index.d.mts +9 -3
- package/dist/index.mjs +5 -2
- package/dist/node.cjs +19 -12
- package/dist/node.d.cts +15 -10
- package/dist/node.d.mts +15 -10
- package/dist/node.mjs +19 -13
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/schema/dsl.cjs +19 -2
- package/dist/schema/dsl.mjs +17 -3
- package/dist/schema/index.cjs +1 -8
- package/dist/schema/index.mjs +2 -8
- package/dist/schema/types.cjs +3 -1
- package/dist/schema/types.mjs +3 -2
- package/dist/schema/v1_0_0.cjs +364 -0
- package/dist/schema/v1_0_0.mjs +357 -0
- package/dist/storageAccess.cjs +69 -25
- package/dist/storageAccess.mjs +68 -25
- package/dist/types/index.d.cts +4 -3
- package/dist/types/index.d.mts +5 -4
- package/package.json +8 -7
- package/src/adapters/databaseConstraintErrors.ts +25 -0
- package/src/adapters/databasePluginTestDatabase.ts +106 -0
- package/src/adapters/databasePluginUtils.spec.ts +29 -0
- package/src/adapters/databasePluginUtils.ts +214 -0
- package/src/adapters/drizzle.spec.ts +208 -47
- package/src/adapters/drizzle.ts +106 -293
- package/src/adapters/drizzleCrud.ts +419 -0
- package/src/adapters/drizzleLazyDB.ts +206 -100
- package/src/adapters/drizzleQuery.ts +164 -0
- package/src/adapters/kysely.spec.ts +126 -88
- package/src/adapters/kysely.ts +76 -334
- package/src/adapters/kyselyCrud.ts +588 -0
- package/src/adapters/kyselyQuery.ts +128 -0
- package/src/adapters/mongodb.spec.ts +141 -0
- package/src/adapters/mongodb.ts +60 -288
- package/src/adapters/mongodbCollections.ts +62 -0
- package/src/adapters/mongodbQuery.ts +226 -0
- package/src/adapters/mongodbReads.ts +311 -0
- package/src/adapters/mongodbRows.spec.ts +64 -0
- package/src/adapters/mongodbRows.ts +118 -0
- package/src/adapters/mongodbTestClient.ts +342 -0
- package/src/adapters/mongodbTestFilter.ts +166 -0
- package/src/adapters/mongodbWrites.ts +260 -0
- package/src/adapters/prisma.spec.ts +196 -0
- package/src/adapters/prisma.ts +417 -292
- package/src/adapters/prismaQuery.ts +129 -0
- package/src/adapters/prismaRows.spec.ts +98 -0
- package/src/adapters/prismaRows.ts +301 -0
- package/src/adapters/prismaTestClient.ts +396 -0
- package/src/analytics/analytics.integration.spec.ts +144 -0
- package/src/analytics/bounded/activeOverview.spec.ts +189 -0
- package/src/analytics/bounded/activeOverview.ts +148 -0
- package/src/analytics/bounded/installationSearch.spec.ts +130 -0
- package/src/analytics/bounded/installationSearch.ts +69 -0
- package/src/analytics/bounded/persistence.ts +43 -0
- package/src/analytics/bounded/provider.spec.ts +219 -0
- package/src/analytics/bounded/provider.ts +229 -0
- package/src/analytics/bounded/scan.ts +235 -0
- package/src/analytics/domain.ts +139 -0
- package/src/analytics/errors.ts +18 -0
- package/src/analytics/eventInput.ts +168 -0
- package/src/analytics/persistence.ts +10 -0
- package/src/analytics/queryInput.ts +102 -0
- package/src/analytics/routes.ts +123 -0
- package/src/analytics/types.ts +44 -0
- package/src/apiKeys.integration.spec.ts +192 -0
- package/src/apiKeys.spec.ts +162 -0
- package/src/apiKeys.ts +220 -0
- package/src/createHotUpdaterCore.ts +164 -100
- package/src/db/bundleRows.spec.ts +164 -0
- package/src/db/bundleRows.ts +10 -140
- package/src/db/createBundleDiff.spec.ts +172 -127
- package/src/db/createBundleDiff.ts +91 -110
- package/src/db/databasePluginCore.spec.ts +62 -0
- package/src/db/databasePluginCore.testFixtures.ts +76 -0
- package/src/db/databasePluginCore.ts +185 -0
- package/src/db/databasePluginUpdateCheck.bench.ts +107 -0
- package/src/db/fixedMigrator.spec.ts +184 -42
- package/src/db/fixedMigrator.ts +64 -205
- package/src/db/fixedMigratorMongo.spec.ts +192 -0
- package/src/db/fixedMigratorMongo.ts +425 -0
- package/src/db/fixedMigratorShared.ts +36 -0
- package/src/db/hotUpdaterSchema.ts +0 -1
- package/src/db/index.spec.ts +333 -1025
- package/src/db/mongoMigrationExecution.ts +23 -0
- package/src/db/node-sqlite.d.ts +25 -0
- package/src/db/releaseCatalog.ts +148 -0
- package/src/db/schema/mongodb.ts +20 -6
- package/src/db/schema/sql.ts +52 -11
- package/src/db/schema/sqlOperations.ts +5 -4
- package/src/db/schemaGenerators.ts +107 -23
- package/src/db/schemaReadiness.ts +2 -1
- package/src/db/sqlMigrationExecution.spec.ts +65 -0
- package/src/db/sqlMigrationExecution.ts +108 -0
- package/src/db/types.spec.ts +55 -0
- package/src/db/types.ts +129 -65
- package/src/db/updateArtifacts.spec.ts +359 -0
- package/src/db/updateArtifacts.ts +290 -126
- package/src/handler-standalone.integration.spec.ts +401 -364
- package/src/handler.spec.ts +137 -582
- package/src/handler.testFixtures.ts +30 -0
- package/src/handler.ts +218 -616
- package/src/handlerAuth.integration.spec.ts +33 -0
- package/src/handlerBundleRoutes.ts +259 -0
- package/src/handlerErrors.ts +7 -0
- package/src/handlerManagement.spec.ts +262 -0
- package/src/handlerParameters.ts +105 -0
- package/src/handlerReleaseCatalogRoutes.ts +154 -0
- package/src/handlerReleaseManagementRoutes.ts +213 -0
- package/src/handlerTypes.ts +96 -0
- package/src/handlerVersionRoutes.ts +12 -0
- package/src/index.ts +22 -2
- package/src/node.spec.ts +79 -10
- package/src/node.ts +20 -17
- package/src/releaseCatalogRoutes.integration.spec.ts +238 -0
- package/src/runtime.spec.ts +126 -959
- package/src/runtime.testFixtures.ts +71 -0
- package/src/schema/dsl-all-versions.spec.ts +26 -17
- package/src/schema/dsl.ts +41 -2
- package/src/schema/index.ts +3 -9
- package/src/schema/types.ts +9 -3
- package/src/schema/v1_0_0.spec.ts +146 -0
- package/src/schema/v1_0_0.ts +465 -0
- package/src/storageAccess.spec.ts +127 -32
- package/src/storageAccess.ts +106 -55
- package/src/types/index.ts +2 -1
- package/dist/db/bundleRows.cjs +0 -82
- package/dist/db/bundleRows.d.cts +0 -33
- package/dist/db/bundleRows.d.mts +0 -33
- package/dist/db/bundleRows.mjs +0 -79
- package/dist/db/pluginCore.cjs +0 -242
- package/dist/db/pluginCore.mjs +0 -241
- package/dist/db/schema/sqlMigrations.cjs +0 -74
- package/dist/db/schema/sqlMigrations.mjs +0 -73
- package/dist/db/schemaEnhancements.cjs +0 -20
- package/dist/db/schemaEnhancements.mjs +0 -19
- package/dist/route.cjs +0 -7
- package/dist/route.mjs +0 -7
- package/dist/schema/v0_21_0.cjs +0 -38
- package/dist/schema/v0_21_0.mjs +0 -37
- package/dist/schema/v0_29_0.cjs +0 -45
- package/dist/schema/v0_29_0.mjs +0 -44
- package/dist/schema/v0_31_0.cjs +0 -82
- package/dist/schema/v0_31_0.mjs +0 -80
- package/src/db/pluginCore.spec.ts +0 -1095
- package/src/db/pluginCore.ts +0 -475
- package/src/db/pluginUpdateCheck.bench.ts +0 -254
- package/src/db/schema/sqlMigrations.ts +0 -219
- package/src/db/schemaEnhancements.ts +0 -55
- package/src/route.ts +0 -7
- package/src/schema/v0_21_0.ts +0 -52
- package/src/schema/v0_29_0.ts +0 -62
- package/src/schema/v0_31_0.spec.ts +0 -73
- package/src/schema/v0_31_0.ts +0 -120
|
@@ -4,33 +4,97 @@ import {
|
|
|
4
4
|
getManifestFileHash,
|
|
5
5
|
getManifestStorageUri,
|
|
6
6
|
stripBundleArtifactMetadata,
|
|
7
|
-
type
|
|
7
|
+
type ArtifactInfo,
|
|
8
8
|
type Bundle,
|
|
9
9
|
type ChangedAsset,
|
|
10
10
|
} from "@hot-updater/core";
|
|
11
11
|
import {
|
|
12
12
|
getManifestAssetDownloadPath,
|
|
13
|
+
isContentAddressedAssetFileHash,
|
|
13
14
|
resolveManifestAssetStorageUri,
|
|
14
|
-
type HotUpdaterContext,
|
|
15
15
|
} from "@hot-updater/plugin-core";
|
|
16
16
|
|
|
17
|
+
type BundleManifestAsset = {
|
|
18
|
+
downloadByteSize?: unknown;
|
|
19
|
+
downloadFileHash?: unknown;
|
|
20
|
+
fileHash: string;
|
|
21
|
+
signature?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
17
24
|
type BundleManifest = {
|
|
18
25
|
bundleId: string;
|
|
19
|
-
assets: Record<string,
|
|
26
|
+
assets: Record<string, BundleManifestAsset>;
|
|
20
27
|
};
|
|
21
28
|
|
|
22
|
-
type
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
type PlannedFile = {
|
|
30
|
+
byteSize: number | null;
|
|
31
|
+
compression?: "br";
|
|
32
|
+
storageUri: string;
|
|
33
|
+
};
|
|
26
34
|
|
|
27
|
-
type
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
type PlannedPatch = {
|
|
36
|
+
baseBundleId: string;
|
|
37
|
+
baseFileHash: string;
|
|
38
|
+
byteSize: number | null;
|
|
39
|
+
patchFileHash: string;
|
|
40
|
+
storageUri: string;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
type PlannedChangedAsset = {
|
|
44
|
+
assetPath: string;
|
|
45
|
+
file: PlannedFile;
|
|
46
|
+
fileHash: string;
|
|
47
|
+
patch: PlannedPatch | null;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type ManifestArtifactPlan = {
|
|
51
|
+
allPossibleByteSizesKnown: boolean;
|
|
52
|
+
changedAssets: PlannedChangedAsset[];
|
|
53
|
+
manifestByteSize: number | null;
|
|
54
|
+
minimumDownloadByteSize: number | null;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
type ResolvedChangedAssets = {
|
|
58
|
+
changedAssets: Record<string, ChangedAsset>;
|
|
59
|
+
primaryByteSizes: Array<number | null>;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
type ResolveFileUrl = (storageUri: string | null) => Promise<string | null>;
|
|
63
|
+
|
|
64
|
+
type ReadStorageText = (storageUri: string) => Promise<string | null>;
|
|
31
65
|
|
|
32
66
|
const HBC_ASSET_PATH_RE = /\.bundle$/;
|
|
33
67
|
|
|
68
|
+
const asByteSize = (value: unknown): number | null =>
|
|
69
|
+
typeof value === "number" && Number.isSafeInteger(value) && value >= 0
|
|
70
|
+
? value
|
|
71
|
+
: null;
|
|
72
|
+
|
|
73
|
+
const sumByteSizes = (byteSizes: Array<number | null>): number | null => {
|
|
74
|
+
let total = 0;
|
|
75
|
+
|
|
76
|
+
for (const byteSize of byteSizes) {
|
|
77
|
+
if (byteSize === null || total > Number.MAX_SAFE_INTEGER - byteSize) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
total += byteSize;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return total;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const shouldUseArchive = (
|
|
87
|
+
targetBundle: Bundle,
|
|
88
|
+
downloadByteSize: number | null,
|
|
89
|
+
) => {
|
|
90
|
+
const archiveByteSize = asByteSize(targetBundle.archiveByteSize);
|
|
91
|
+
return (
|
|
92
|
+
archiveByteSize !== null &&
|
|
93
|
+
downloadByteSize !== null &&
|
|
94
|
+
downloadByteSize >= archiveByteSize
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
34
98
|
const resolveUniqueHbcAssetPath = (manifest: BundleManifest) => {
|
|
35
99
|
const candidates = Object.keys(manifest.assets)
|
|
36
100
|
.sort((left, right) => left.localeCompare(right))
|
|
@@ -133,16 +197,14 @@ export const parseBundleRawMetadata = (
|
|
|
133
197
|
return parsedValue as Bundle["metadata"];
|
|
134
198
|
};
|
|
135
199
|
|
|
136
|
-
async function fetchBundleManifest
|
|
200
|
+
async function fetchBundleManifest(
|
|
137
201
|
storageUri: string,
|
|
138
|
-
readStorageText: ReadStorageText
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
resolveFileUrl(storageUri, context),
|
|
145
|
-
]);
|
|
202
|
+
readStorageText: ReadStorageText,
|
|
203
|
+
): Promise<{
|
|
204
|
+
byteSize: number | null;
|
|
205
|
+
manifest: BundleManifest;
|
|
206
|
+
} | null> {
|
|
207
|
+
const storageText = await readStorageText(storageUri);
|
|
146
208
|
if (storageText === null) {
|
|
147
209
|
return null;
|
|
148
210
|
}
|
|
@@ -158,68 +220,191 @@ async function fetchBundleManifest<TContext>(
|
|
|
158
220
|
return null;
|
|
159
221
|
}
|
|
160
222
|
|
|
161
|
-
|
|
223
|
+
return {
|
|
224
|
+
byteSize: asByteSize(new TextEncoder().encode(storageText).byteLength),
|
|
225
|
+
manifest: payload,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function resolveHbcPatchPlan({
|
|
230
|
+
currentBundle,
|
|
231
|
+
targetBundle,
|
|
232
|
+
targetManifest,
|
|
233
|
+
}: {
|
|
234
|
+
currentBundle: Bundle | null;
|
|
235
|
+
targetBundle: Bundle;
|
|
236
|
+
targetManifest: BundleManifest;
|
|
237
|
+
}): { assetPath: string; patch: PlannedPatch } | null {
|
|
238
|
+
const matchingPatch = currentBundle
|
|
239
|
+
? getBundlePatch(targetBundle, currentBundle.id)
|
|
240
|
+
: null;
|
|
241
|
+
const patchAssetPath = resolveUniqueHbcAssetPath(targetManifest);
|
|
242
|
+
|
|
243
|
+
if (
|
|
244
|
+
!currentBundle ||
|
|
245
|
+
!matchingPatch ||
|
|
246
|
+
!patchAssetPath ||
|
|
247
|
+
!matchingPatch.patchStorageUri ||
|
|
248
|
+
!matchingPatch.patchFileHash ||
|
|
249
|
+
!matchingPatch.baseFileHash
|
|
250
|
+
) {
|
|
162
251
|
return null;
|
|
163
252
|
}
|
|
164
253
|
|
|
165
254
|
return {
|
|
166
|
-
|
|
167
|
-
|
|
255
|
+
assetPath: patchAssetPath,
|
|
256
|
+
patch: {
|
|
257
|
+
baseBundleId: matchingPatch.baseBundleId,
|
|
258
|
+
baseFileHash: matchingPatch.baseFileHash,
|
|
259
|
+
byteSize: asByteSize(matchingPatch.byteSize),
|
|
260
|
+
patchFileHash: matchingPatch.patchFileHash,
|
|
261
|
+
storageUri: matchingPatch.patchStorageUri,
|
|
262
|
+
},
|
|
168
263
|
};
|
|
169
264
|
}
|
|
170
265
|
|
|
171
|
-
|
|
266
|
+
function createManifestArtifactPlan({
|
|
172
267
|
assetBaseStorageUri,
|
|
173
268
|
currentManifest,
|
|
174
269
|
currentBundle,
|
|
175
|
-
resolveFileUrl,
|
|
176
270
|
targetBundle,
|
|
177
271
|
targetManifest,
|
|
178
|
-
|
|
272
|
+
targetManifestByteSize,
|
|
179
273
|
}: {
|
|
180
274
|
assetBaseStorageUri: string;
|
|
181
275
|
currentManifest: BundleManifest | null;
|
|
182
276
|
currentBundle: Bundle | null;
|
|
183
|
-
|
|
184
|
-
targetBundle: Bundle | null;
|
|
277
|
+
targetBundle: Bundle;
|
|
185
278
|
targetManifest: BundleManifest;
|
|
186
|
-
|
|
187
|
-
}):
|
|
188
|
-
const
|
|
279
|
+
targetManifestByteSize: number | null;
|
|
280
|
+
}): ManifestArtifactPlan {
|
|
281
|
+
const patchCandidate = resolveHbcPatchPlan({
|
|
189
282
|
currentBundle,
|
|
190
|
-
resolveFileUrl,
|
|
191
283
|
targetBundle,
|
|
192
284
|
targetManifest,
|
|
193
|
-
context,
|
|
194
285
|
});
|
|
195
|
-
const
|
|
196
|
-
|
|
286
|
+
const changedAssets = Object.entries(targetManifest.assets).flatMap(
|
|
287
|
+
([assetPath, asset]): PlannedChangedAsset[] => {
|
|
197
288
|
const currentAsset = currentManifest?.assets[assetPath];
|
|
198
289
|
if (currentAsset?.fileHash === asset.fileHash) {
|
|
199
|
-
return
|
|
290
|
+
return [];
|
|
200
291
|
}
|
|
201
292
|
|
|
293
|
+
const downloadByteSize = asByteSize(asset.downloadByteSize);
|
|
202
294
|
const downloadPath = getManifestAssetDownloadPath(assetPath);
|
|
203
|
-
const
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
295
|
+
const isTransformedDownload = downloadPath !== assetPath;
|
|
296
|
+
const hasValidDownloadFileHash = isContentAddressedAssetFileHash(
|
|
297
|
+
asset.downloadFileHash,
|
|
298
|
+
);
|
|
299
|
+
const hasKnownDownloadByteSize =
|
|
300
|
+
downloadByteSize !== null &&
|
|
301
|
+
(hasValidDownloadFileHash ||
|
|
302
|
+
(!isTransformedDownload && asset.downloadFileHash === undefined));
|
|
303
|
+
const file: PlannedFile = {
|
|
304
|
+
byteSize: hasKnownDownloadByteSize ? downloadByteSize : null,
|
|
305
|
+
storageUri: resolveManifestAssetStorageUri({
|
|
306
|
+
assetBaseStorageUri,
|
|
307
|
+
assetPath: downloadPath,
|
|
308
|
+
downloadFileHash: asset.downloadFileHash,
|
|
309
|
+
fileHash: asset.fileHash,
|
|
310
|
+
}),
|
|
311
|
+
};
|
|
312
|
+
if (isTransformedDownload) {
|
|
313
|
+
file.compression = "br";
|
|
314
|
+
}
|
|
315
|
+
|
|
209
316
|
const patch =
|
|
210
|
-
|
|
317
|
+
patchCandidate?.assetPath === assetPath ? patchCandidate.patch : null;
|
|
318
|
+
|
|
319
|
+
return [
|
|
320
|
+
{
|
|
321
|
+
assetPath,
|
|
322
|
+
file,
|
|
323
|
+
fileHash: asset.fileHash,
|
|
324
|
+
patch,
|
|
325
|
+
},
|
|
326
|
+
];
|
|
327
|
+
},
|
|
328
|
+
);
|
|
329
|
+
const allPossibleByteSizesKnown =
|
|
330
|
+
targetManifestByteSize !== null &&
|
|
331
|
+
changedAssets.every(
|
|
332
|
+
(asset) =>
|
|
333
|
+
asset.file.byteSize !== null &&
|
|
334
|
+
(asset.patch === null || asset.patch.byteSize !== null),
|
|
335
|
+
);
|
|
336
|
+
const primaryByteSizes = changedAssets.map((asset) => {
|
|
337
|
+
if (!asset.patch) return asset.file.byteSize;
|
|
338
|
+
if (asset.patch.byteSize === null || asset.file.byteSize === null) {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
return Math.min(asset.patch.byteSize, asset.file.byteSize);
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
return {
|
|
345
|
+
allPossibleByteSizesKnown,
|
|
346
|
+
changedAssets,
|
|
347
|
+
manifestByteSize: targetManifestByteSize,
|
|
348
|
+
minimumDownloadByteSize: allPossibleByteSizesKnown
|
|
349
|
+
? sumByteSizes([targetManifestByteSize, ...primaryByteSizes])
|
|
350
|
+
: null,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
async function resolveChangedAssets(
|
|
355
|
+
plan: ManifestArtifactPlan,
|
|
356
|
+
resolveFileUrl: ResolveFileUrl,
|
|
357
|
+
): Promise<ResolvedChangedAssets | null> {
|
|
358
|
+
const patchAsset = plan.changedAssets.find((asset) => asset.patch !== null);
|
|
359
|
+
let resolvedPatch: {
|
|
360
|
+
assetPath: string;
|
|
361
|
+
patch: NonNullable<ChangedAsset["patch"]>;
|
|
362
|
+
} | null = null;
|
|
363
|
+
|
|
364
|
+
if (patchAsset?.patch) {
|
|
365
|
+
const patchUrl = await resolveFileUrl(patchAsset.patch.storageUri);
|
|
366
|
+
if (patchUrl) {
|
|
367
|
+
resolvedPatch = {
|
|
368
|
+
assetPath: patchAsset.assetPath,
|
|
369
|
+
patch: {
|
|
370
|
+
algorithm: "bsdiff",
|
|
371
|
+
baseBundleId: patchAsset.patch.baseBundleId,
|
|
372
|
+
baseFileHash: patchAsset.patch.baseFileHash,
|
|
373
|
+
patchFileHash: patchAsset.patch.patchFileHash,
|
|
374
|
+
patchUrl,
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
}
|
|
211
379
|
|
|
380
|
+
const changedEntries = await Promise.all(
|
|
381
|
+
plan.changedAssets.map(async (asset) => {
|
|
382
|
+
let patch =
|
|
383
|
+
resolvedPatch?.assetPath === asset.assetPath
|
|
384
|
+
? resolvedPatch.patch
|
|
385
|
+
: null;
|
|
212
386
|
let fileUrl: string | null = null;
|
|
213
387
|
try {
|
|
214
|
-
fileUrl = await resolveFileUrl(storageUri
|
|
388
|
+
fileUrl = await resolveFileUrl(asset.file.storageUri);
|
|
215
389
|
} catch (error) {
|
|
216
390
|
if (!patch) {
|
|
217
391
|
throw error;
|
|
218
392
|
}
|
|
219
393
|
}
|
|
220
394
|
|
|
395
|
+
if (
|
|
396
|
+
fileUrl &&
|
|
397
|
+
patch &&
|
|
398
|
+
asset.file.byteSize !== null &&
|
|
399
|
+
asset.patch !== null &&
|
|
400
|
+
asset.patch.byteSize !== null &&
|
|
401
|
+
asset.patch.byteSize >= asset.file.byteSize
|
|
402
|
+
) {
|
|
403
|
+
patch = null;
|
|
404
|
+
}
|
|
405
|
+
|
|
221
406
|
if (!fileUrl && !patch) {
|
|
222
|
-
return
|
|
407
|
+
return null;
|
|
223
408
|
}
|
|
224
409
|
|
|
225
410
|
const changedAsset: ChangedAsset = {
|
|
@@ -229,93 +414,52 @@ async function resolveChangedAssets<TContext>({
|
|
|
229
414
|
changedAsset.file = {
|
|
230
415
|
url: fileUrl,
|
|
231
416
|
};
|
|
232
|
-
if (
|
|
233
|
-
changedAsset.file.compression =
|
|
417
|
+
if (asset.file.compression) {
|
|
418
|
+
changedAsset.file.compression = asset.file.compression;
|
|
234
419
|
}
|
|
235
420
|
}
|
|
236
421
|
if (patch) {
|
|
237
422
|
changedAsset.patch = patch;
|
|
238
423
|
}
|
|
239
424
|
|
|
240
|
-
return
|
|
425
|
+
return {
|
|
426
|
+
asset: [asset.assetPath, changedAsset] as const,
|
|
427
|
+
primaryByteSize: patch
|
|
428
|
+
? (asset.patch?.byteSize ?? null)
|
|
429
|
+
: asset.file.byteSize,
|
|
430
|
+
};
|
|
241
431
|
}),
|
|
242
432
|
);
|
|
243
433
|
|
|
244
|
-
if (changedEntries.some((entry) => entry ===
|
|
434
|
+
if (changedEntries.some((entry) => entry === null)) {
|
|
245
435
|
return null;
|
|
246
436
|
}
|
|
247
437
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
(entry): entry is readonly [string, ChangedAsset] => entry !== null,
|
|
251
|
-
),
|
|
438
|
+
const resolvedEntries = changedEntries.filter(
|
|
439
|
+
(entry): entry is NonNullable<typeof entry> => entry !== null,
|
|
252
440
|
);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
async function resolveHbcPatchDescriptor<TContext>({
|
|
256
|
-
currentBundle,
|
|
257
|
-
resolveFileUrl,
|
|
258
|
-
targetBundle,
|
|
259
|
-
targetManifest,
|
|
260
|
-
context,
|
|
261
|
-
}: {
|
|
262
|
-
currentBundle: Bundle | null;
|
|
263
|
-
resolveFileUrl: ResolveFileUrl<TContext>;
|
|
264
|
-
targetBundle: Bundle | null;
|
|
265
|
-
targetManifest: BundleManifest;
|
|
266
|
-
context?: HotUpdaterContext<TContext>;
|
|
267
|
-
}): Promise<{
|
|
268
|
-
assetPath: string;
|
|
269
|
-
patch: ChangedAsset["patch"];
|
|
270
|
-
} | null> {
|
|
271
|
-
const matchingPatch =
|
|
272
|
-
targetBundle && currentBundle
|
|
273
|
-
? getBundlePatch(targetBundle, currentBundle.id)
|
|
274
|
-
: null;
|
|
275
|
-
const patchAssetPath = resolveUniqueHbcAssetPath(targetManifest);
|
|
276
|
-
|
|
277
|
-
if (
|
|
278
|
-
!currentBundle ||
|
|
279
|
-
!matchingPatch ||
|
|
280
|
-
!patchAssetPath ||
|
|
281
|
-
!matchingPatch.patchStorageUri ||
|
|
282
|
-
!matchingPatch.patchFileHash ||
|
|
283
|
-
!matchingPatch.baseFileHash
|
|
284
|
-
) {
|
|
285
|
-
return null;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const patchUrl = await resolveFileUrl(matchingPatch.patchStorageUri, context);
|
|
289
|
-
if (!patchUrl) {
|
|
290
|
-
return null;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
441
|
return {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
baseFileHash: matchingPatch.baseFileHash,
|
|
299
|
-
patchFileHash: matchingPatch.patchFileHash,
|
|
300
|
-
patchUrl,
|
|
301
|
-
},
|
|
442
|
+
changedAssets: Object.fromEntries(
|
|
443
|
+
resolvedEntries.map((entry) => entry.asset),
|
|
444
|
+
),
|
|
445
|
+
primaryByteSizes: resolvedEntries.map((entry) => entry.primaryByteSize),
|
|
302
446
|
};
|
|
303
447
|
}
|
|
304
448
|
|
|
305
|
-
export async function resolveManifestArtifacts
|
|
449
|
+
export async function resolveManifestArtifacts({
|
|
450
|
+
archiveUrlUsable,
|
|
306
451
|
currentBundle,
|
|
307
452
|
resolveFileUrl,
|
|
308
453
|
readStorageText,
|
|
309
454
|
targetBundle,
|
|
310
|
-
context,
|
|
311
455
|
}: {
|
|
456
|
+
archiveUrlUsable: boolean;
|
|
312
457
|
currentBundle: Bundle | null;
|
|
313
|
-
resolveFileUrl: ResolveFileUrl
|
|
314
|
-
readStorageText: ReadStorageText
|
|
458
|
+
resolveFileUrl: ResolveFileUrl;
|
|
459
|
+
readStorageText: ReadStorageText;
|
|
315
460
|
targetBundle: Bundle | null;
|
|
316
|
-
context?: HotUpdaterContext<TContext>;
|
|
317
461
|
}): Promise<Pick<
|
|
318
|
-
|
|
462
|
+
ArtifactInfo,
|
|
319
463
|
"changedAssets" | "manifestFileHash" | "manifestUrl"
|
|
320
464
|
> | null> {
|
|
321
465
|
const manifestStorageUri = targetBundle
|
|
@@ -328,7 +472,12 @@ export async function resolveManifestArtifacts<TContext>({
|
|
|
328
472
|
? getAssetBaseStorageUri(targetBundle)
|
|
329
473
|
: null;
|
|
330
474
|
|
|
331
|
-
if (
|
|
475
|
+
if (
|
|
476
|
+
!targetBundle ||
|
|
477
|
+
!manifestStorageUri ||
|
|
478
|
+
!manifestFileHash ||
|
|
479
|
+
!assetBaseStorageUri
|
|
480
|
+
) {
|
|
332
481
|
return null;
|
|
333
482
|
}
|
|
334
483
|
|
|
@@ -336,19 +485,9 @@ export async function resolveManifestArtifacts<TContext>({
|
|
|
336
485
|
? getManifestStorageUri(currentBundle)
|
|
337
486
|
: null;
|
|
338
487
|
const [targetManifestResult, currentManifestResult] = await Promise.all([
|
|
339
|
-
fetchBundleManifest(
|
|
340
|
-
manifestStorageUri,
|
|
341
|
-
readStorageText,
|
|
342
|
-
resolveFileUrl,
|
|
343
|
-
context,
|
|
344
|
-
),
|
|
488
|
+
fetchBundleManifest(manifestStorageUri, readStorageText),
|
|
345
489
|
currentManifestStorageUri
|
|
346
|
-
? fetchBundleManifest(
|
|
347
|
-
currentManifestStorageUri,
|
|
348
|
-
readStorageText,
|
|
349
|
-
resolveFileUrl,
|
|
350
|
-
context,
|
|
351
|
-
)
|
|
490
|
+
? fetchBundleManifest(currentManifestStorageUri, readStorageText)
|
|
352
491
|
: null,
|
|
353
492
|
]);
|
|
354
493
|
|
|
@@ -356,22 +495,47 @@ export async function resolveManifestArtifacts<TContext>({
|
|
|
356
495
|
return null;
|
|
357
496
|
}
|
|
358
497
|
|
|
359
|
-
const
|
|
498
|
+
const plan = createManifestArtifactPlan({
|
|
360
499
|
assetBaseStorageUri,
|
|
361
500
|
currentManifest: currentManifestResult?.manifest ?? null,
|
|
362
501
|
currentBundle,
|
|
363
|
-
resolveFileUrl,
|
|
364
502
|
targetBundle,
|
|
365
503
|
targetManifest: targetManifestResult.manifest,
|
|
366
|
-
|
|
504
|
+
targetManifestByteSize: targetManifestResult.byteSize,
|
|
367
505
|
});
|
|
368
|
-
|
|
506
|
+
|
|
507
|
+
if (
|
|
508
|
+
archiveUrlUsable &&
|
|
509
|
+
plan.allPossibleByteSizesKnown &&
|
|
510
|
+
shouldUseArchive(targetBundle, plan.minimumDownloadByteSize)
|
|
511
|
+
) {
|
|
512
|
+
return null;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const manifestUrl = await resolveFileUrl(manifestStorageUri);
|
|
516
|
+
if (!manifestUrl) {
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const resolved = await resolveChangedAssets(plan, resolveFileUrl);
|
|
521
|
+
if (!resolved) {
|
|
522
|
+
return null;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
const resolvedDownloadByteSize = sumByteSizes([
|
|
526
|
+
plan.manifestByteSize,
|
|
527
|
+
...resolved.primaryByteSizes,
|
|
528
|
+
]);
|
|
529
|
+
if (
|
|
530
|
+
archiveUrlUsable &&
|
|
531
|
+
shouldUseArchive(targetBundle, resolvedDownloadByteSize)
|
|
532
|
+
) {
|
|
369
533
|
return null;
|
|
370
534
|
}
|
|
371
535
|
|
|
372
536
|
return {
|
|
373
|
-
changedAssets,
|
|
537
|
+
changedAssets: resolved.changedAssets,
|
|
374
538
|
manifestFileHash,
|
|
375
|
-
manifestUrl
|
|
539
|
+
manifestUrl,
|
|
376
540
|
};
|
|
377
541
|
}
|