@hot-updater/plugin-core 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.
Files changed (161) hide show
  1. package/dist/assetStorageLayout.cjs +36 -18
  2. package/dist/assetStorageLayout.d.cts +21 -6
  3. package/dist/assetStorageLayout.d.mts +21 -6
  4. package/dist/assetStorageLayout.mjs +36 -18
  5. package/dist/bundleStorageLayout.cjs +2 -3
  6. package/dist/bundleStorageLayout.mjs +2 -3
  7. package/dist/contentAddressedAssets.cjs +5 -0
  8. package/dist/contentAddressedAssets.d.cts +2 -1
  9. package/dist/contentAddressedAssets.d.mts +2 -1
  10. package/dist/contentAddressedAssets.mjs +5 -1
  11. package/dist/createDatabasePlugin.cjs +775 -284
  12. package/dist/createDatabasePlugin.d.cts +20 -64
  13. package/dist/createDatabasePlugin.d.mts +20 -64
  14. package/dist/createDatabasePlugin.mjs +773 -284
  15. package/dist/createStorageKeyBuilder.cjs +9 -2
  16. package/dist/createStorageKeyBuilder.mjs +9 -2
  17. package/dist/createStoragePlugin.cjs +6 -145
  18. package/dist/createStoragePlugin.d.cts +7 -52
  19. package/dist/createStoragePlugin.d.mts +7 -52
  20. package/dist/createStoragePlugin.mjs +5 -143
  21. package/dist/databaseClient.cjs +112 -0
  22. package/dist/databaseClient.d.cts +33 -0
  23. package/dist/databaseClient.d.mts +33 -0
  24. package/dist/databaseClient.mjs +110 -0
  25. package/dist/databaseClientReads.cjs +113 -0
  26. package/dist/databaseClientReads.mjs +112 -0
  27. package/dist/databaseClientUpdates.cjs +39 -0
  28. package/dist/databaseClientUpdates.d.cts +11 -0
  29. package/dist/databaseClientUpdates.d.mts +11 -0
  30. package/dist/databaseClientUpdates.mjs +36 -0
  31. package/dist/databaseJsonValue.cjs +37 -0
  32. package/dist/databaseJsonValue.d.cts +5 -0
  33. package/dist/databaseJsonValue.d.mts +5 -0
  34. package/dist/databaseJsonValue.mjs +37 -0
  35. package/dist/databaseMetadata.cjs +13 -0
  36. package/dist/databaseMetadata.mjs +12 -0
  37. package/dist/databasePluginCrud.cjs +86 -0
  38. package/dist/databasePluginCrud.d.cts +1 -0
  39. package/dist/databasePluginCrud.d.mts +1 -0
  40. package/dist/databasePluginCrud.mjs +86 -0
  41. package/dist/databasePluginCrudValidation.d.cts +1 -0
  42. package/dist/databasePluginCrudValidation.d.mts +1 -0
  43. package/dist/databasePluginCrudValidationErrors.cjs +10 -0
  44. package/dist/databasePluginCrudValidationErrors.d.cts +9 -0
  45. package/dist/databasePluginCrudValidationErrors.d.mts +9 -0
  46. package/dist/databasePluginCrudValidationErrors.mjs +10 -0
  47. package/dist/databasePluginCrudValidationFields.cjs +291 -0
  48. package/dist/databasePluginCrudValidationFields.d.cts +1 -0
  49. package/dist/databasePluginCrudValidationFields.d.mts +1 -0
  50. package/dist/databasePluginCrudValidationFields.mjs +281 -0
  51. package/dist/databasePluginCrudValidationMutations.cjs +88 -0
  52. package/dist/databasePluginCrudValidationMutations.d.cts +1 -0
  53. package/dist/databasePluginCrudValidationMutations.d.mts +1 -0
  54. package/dist/databasePluginCrudValidationMutations.mjs +82 -0
  55. package/dist/databasePluginCrudValidationQueries.cjs +103 -0
  56. package/dist/databasePluginCrudValidationQueries.d.cts +1 -0
  57. package/dist/databasePluginCrudValidationQueries.d.mts +1 -0
  58. package/dist/databasePluginCrudValidationQueries.mjs +97 -0
  59. package/dist/databasePluginCrudValidationRows.cjs +55 -0
  60. package/dist/databasePluginCrudValidationRows.d.cts +1 -0
  61. package/dist/databasePluginCrudValidationRows.d.mts +1 -0
  62. package/dist/databasePluginCrudValidationRows.mjs +53 -0
  63. package/dist/databasePluginTransaction.cjs +7 -0
  64. package/dist/databasePluginTransaction.mjs +7 -0
  65. package/dist/databaseRows.cjs +149 -0
  66. package/dist/databaseRows.d.cts +34 -0
  67. package/dist/databaseRows.d.mts +34 -0
  68. package/dist/databaseRows.mjs +141 -0
  69. package/dist/index.cjs +76 -24
  70. package/dist/index.d.cts +22 -12
  71. package/dist/index.d.mts +22 -12
  72. package/dist/index.mjs +21 -14
  73. package/dist/internal.cjs +6 -0
  74. package/dist/internal.d.cts +9 -0
  75. package/dist/internal.d.mts +9 -0
  76. package/dist/internal.mjs +3 -0
  77. package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.cjs +345 -0
  78. package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.mjs +341 -0
  79. package/dist/paginateBundles.d.cts +6 -4
  80. package/dist/paginateBundles.d.mts +6 -4
  81. package/dist/parseStorageUri.cjs +46 -30
  82. package/dist/parseStorageUri.d.cts +20 -17
  83. package/dist/parseStorageUri.d.mts +20 -17
  84. package/dist/parseStorageUri.mjs +46 -30
  85. package/dist/queryBundles.cjs +1 -7
  86. package/dist/queryBundles.d.cts +3 -1
  87. package/dist/queryBundles.d.mts +3 -1
  88. package/dist/queryBundles.mjs +1 -7
  89. package/dist/releaseCatalogCompiler.cjs +391 -0
  90. package/dist/releaseCatalogCompiler.d.cts +55 -0
  91. package/dist/releaseCatalogCompiler.d.mts +55 -0
  92. package/dist/releaseCatalogCompiler.mjs +386 -0
  93. package/dist/releaseCatalogMutation.cjs +303 -0
  94. package/dist/releaseCatalogMutation.d.cts +86 -0
  95. package/dist/releaseCatalogMutation.d.mts +86 -0
  96. package/dist/releaseCatalogMutation.mjs +297 -0
  97. package/dist/releaseManagement.cjs +231 -0
  98. package/dist/releaseManagement.d.cts +48 -0
  99. package/dist/releaseManagement.d.mts +48 -0
  100. package/dist/releaseManagement.mjs +224 -0
  101. package/dist/remoteBundleSigning.cjs +296 -0
  102. package/dist/remoteBundleSigning.d.cts +43 -0
  103. package/dist/remoteBundleSigning.d.mts +43 -0
  104. package/dist/remoteBundleSigning.mjs +291 -0
  105. package/dist/requestBundleCache.cjs +22 -0
  106. package/dist/requestBundleCache.d.cts +9 -0
  107. package/dist/requestBundleCache.d.mts +9 -0
  108. package/dist/requestBundleCache.mjs +22 -0
  109. package/dist/semverSatisfies.cjs +3 -4
  110. package/dist/semverSatisfies.mjs +1 -1
  111. package/dist/storageDownloadPath.cjs +48 -0
  112. package/dist/storageDownloadPath.d.cts +15 -0
  113. package/dist/storageDownloadPath.d.mts +15 -0
  114. package/dist/storageDownloadPath.mjs +46 -0
  115. package/dist/types/database.d.cts +4 -0
  116. package/dist/types/database.d.mts +4 -0
  117. package/dist/types/databaseFields.cjs +92 -0
  118. package/dist/types/databaseFields.d.cts +12 -0
  119. package/dist/types/databaseFields.d.mts +12 -0
  120. package/dist/types/databaseFields.mjs +92 -0
  121. package/dist/types/databaseOperations.d.cts +173 -0
  122. package/dist/types/databaseOperations.d.mts +173 -0
  123. package/dist/types/databasePlugin.d.cts +240 -0
  124. package/dist/types/databasePlugin.d.mts +240 -0
  125. package/dist/types/databaseQuery.d.cts +47 -0
  126. package/dist/types/databaseQuery.d.mts +47 -0
  127. package/dist/types/databaseRows.d.cts +120 -0
  128. package/dist/types/databaseRows.d.mts +120 -0
  129. package/dist/types/index.d.cts +120 -162
  130. package/dist/types/index.d.mts +120 -162
  131. package/dist/types/internal.d.cts +7 -0
  132. package/dist/types/internal.d.mts +7 -0
  133. package/dist/types/public.d.cts +3 -0
  134. package/dist/types/public.d.mts +3 -0
  135. package/dist/uuidv7.cjs +9 -0
  136. package/dist/uuidv7.d.cts +4 -1
  137. package/dist/uuidv7.d.mts +4 -1
  138. package/dist/uuidv7.mjs +8 -1
  139. package/package.json +10 -5
  140. package/dist/bundleUnitOfWork.cjs +0 -158
  141. package/dist/bundleUnitOfWork.mjs +0 -158
  142. package/dist/bundleUnitOfWorkStore.cjs +0 -15
  143. package/dist/bundleUnitOfWorkStore.mjs +0 -15
  144. package/dist/createBlobDatabasePlugin.cjs +0 -382
  145. package/dist/createBlobDatabasePlugin.d.cts +0 -29
  146. package/dist/createBlobDatabasePlugin.d.mts +0 -29
  147. package/dist/createBlobDatabasePlugin.mjs +0 -381
  148. package/dist/legacyAssetStorageLayout.cjs +0 -12
  149. package/dist/legacyAssetStorageLayout.mjs +0 -12
  150. package/dist/requestUpdateBundleState.cjs +0 -26
  151. package/dist/requestUpdateBundleState.d.cts +0 -12
  152. package/dist/requestUpdateBundleState.d.mts +0 -12
  153. package/dist/requestUpdateBundleState.mjs +0 -24
  154. package/dist/resolveUpdateInfoFromBundles.cjs +0 -14
  155. package/dist/resolveUpdateInfoFromBundles.d.cts +0 -16
  156. package/dist/resolveUpdateInfoFromBundles.d.mts +0 -16
  157. package/dist/resolveUpdateInfoFromBundles.mjs +0 -13
  158. package/dist/storageProfile.cjs +0 -15
  159. package/dist/storageProfile.d.cts +0 -9
  160. package/dist/storageProfile.d.mts +0 -9
  161. package/dist/storageProfile.mjs +0 -12
@@ -1,381 +0,0 @@
1
- import { bundleMatchesQueryWhere, sortBundles } from "./queryBundles.mjs";
2
- import { createDatabasePlugin } from "./createDatabasePlugin.mjs";
3
- import { filterCompatibleAppVersions } from "./filterCompatibleAppVersions.mjs";
4
- import { paginateBundles } from "./paginateBundles.mjs";
5
- import { resolveUpdateInfoFromBundles } from "./resolveUpdateInfoFromBundles.mjs";
6
- import { orderBy } from "es-toolkit";
7
- import { coerce, normalize, parse } from "verkit";
8
- //#region src/createBlobDatabasePlugin.ts
9
- const STORAGE_OPERATION_CONCURRENCY = 8;
10
- async function mapWithConcurrency(items, concurrency, mapper) {
11
- const results = [];
12
- let nextIndex = 0;
13
- const workerCount = Math.min(concurrency, items.length);
14
- await Promise.all(Array.from({ length: workerCount }, async () => {
15
- while (true) {
16
- const index = nextIndex;
17
- nextIndex += 1;
18
- if (index >= items.length) break;
19
- results[index] = await mapper(items[index], index);
20
- }
21
- }));
22
- return results;
23
- }
24
- async function forEachWithConcurrency(items, concurrency, mapper) {
25
- await mapWithConcurrency(items, concurrency, mapper);
26
- }
27
- function removeBundleInternalKeys(bundle) {
28
- const { _updateJsonKey, _oldUpdateJsonKey, ...pureBundle } = bundle;
29
- return pureBundle;
30
- }
31
- function normalizeTargetAppVersion(version) {
32
- if (!version) return null;
33
- let normalized = version.replace(/\s+/g, " ").trim();
34
- normalized = normalized.replace(/([><=~^]+)\s+(\d)/g, (_match, operator, digit) => `${operator}${digit}`);
35
- return normalized;
36
- }
37
- function isExactVersion(version) {
38
- if (!version) return false;
39
- const normalized = normalizeTargetAppVersion(version);
40
- if (!normalized) return false;
41
- return normalize(normalized) !== null;
42
- }
43
- /**
44
- * Get all normalized semver versions for a version string.
45
- * This handles the case where clients may request with different normalized forms.
46
- *
47
- * Examples:
48
- * - "1.0.0" generates ["1.0.0", "1.0", "1"]
49
- * - "2.1.0" generates ["2.1.0", "2.1"]
50
- * - "1.2.3" generates ["1.2.3"]
51
- */
52
- function getSemverNormalizedVersions(version) {
53
- const normalized = normalizeTargetAppVersion(version) || version;
54
- const coerced = coerce(normalized);
55
- if (!coerced) return [normalized];
56
- const { major, minor, patch } = parse(coerced);
57
- const versions = /* @__PURE__ */ new Set();
58
- versions.add(coerced);
59
- if (patch === 0) versions.add(`${major}.${minor}`);
60
- if (minor === 0 && patch === 0) versions.add(`${major}`);
61
- return Array.from(versions);
62
- }
63
- function resolveStorageTarget({ targetAppVersion, fingerprintHash }) {
64
- const target = normalizeTargetAppVersion(targetAppVersion) ?? fingerprintHash;
65
- if (!target) throw new Error("target not found");
66
- return target;
67
- }
68
- function targetVersionMutationKey(bundle) {
69
- return `${bundle.channel}/${bundle.platform}`;
70
- }
71
- function getTargetVersionMutation(mutations, bundle) {
72
- const key = targetVersionMutationKey(bundle);
73
- const existingMutation = mutations.get(key);
74
- if (existingMutation) return existingMutation;
75
- const mutation = {
76
- additions: /* @__PURE__ */ new Set(),
77
- channel: bundle.channel,
78
- platform: bundle.platform,
79
- removals: /* @__PURE__ */ new Set()
80
- };
81
- mutations.set(key, mutation);
82
- return mutation;
83
- }
84
- function addTargetVersionAddition(mutations, bundle) {
85
- const targetAppVersion = normalizeTargetAppVersion(bundle.targetAppVersion);
86
- if (targetAppVersion == null) return;
87
- getTargetVersionMutation(mutations, bundle).additions.add(targetAppVersion);
88
- }
89
- function addTargetVersionRemoval(mutations, bundle) {
90
- const targetAppVersion = normalizeTargetAppVersion(bundle.targetAppVersion);
91
- if (targetAppVersion == null) return;
92
- getTargetVersionMutation(mutations, bundle).removals.add(targetAppVersion);
93
- }
94
- function getManagementListPrefixes(where) {
95
- if (where?.channel && where.platform && typeof where.targetAppVersion === "string") {
96
- const targetAppVersion = normalizeTargetAppVersion(where.targetAppVersion);
97
- if (targetAppVersion) return [`${where.channel}/${where.platform}/${targetAppVersion}/`];
98
- }
99
- if (where?.channel && where.platform) return [`${where.channel}/${where.platform}/`];
100
- if (where?.channel) return [`${where.channel}/`];
101
- return [""];
102
- }
103
- function getChannelFromUpdateJsonKey(key) {
104
- return key.match(/^([^/]+)\/(?:ios|android)\/[^/]+\/update\.json$/)?.[1] ?? null;
105
- }
106
- const DEFAULT_DESC_ORDER = {
107
- field: "id",
108
- direction: "desc"
109
- };
110
- function sortManagedBundles(bundles, orderBy = DEFAULT_DESC_ORDER) {
111
- return sortBundles(bundles, orderBy);
112
- }
113
- /**
114
- * Creates a blob storage-based database plugin with lazy initialization.
115
- *
116
- * @param name - The name of the database plugin
117
- * @param factory - Function that creates blob storage operations from config
118
- * @returns A double-curried function that lazily initializes the database plugin
119
- */
120
- const createBlobDatabasePlugin = ({ name, factory }) => {
121
- return (config, hooks) => {
122
- const { listObjects, loadObject, uploadObject, deleteObject, shouldSkipLoadObjectError, validateChannel, invalidatePaths, apiBasePath } = factory(config);
123
- const bundlesMap = /* @__PURE__ */ new Map();
124
- const pendingBundlesMap = /* @__PURE__ */ new Map();
125
- const locallyDeletedBundleIds = /* @__PURE__ */ new Set();
126
- const loadOptionalObject = async (key) => {
127
- try {
128
- return await loadObject(key);
129
- } catch (error) {
130
- if (shouldSkipLoadObjectError?.(error, key)) return null;
131
- throw error;
132
- }
133
- };
134
- const loadAllBundlesForManagementFallback = async (where) => {
135
- return sortManagedBundles((await reloadBundles(getManagementListPrefixes(where))).map((bundle) => removeBundleInternalKeys(bundle)));
136
- };
137
- const cacheBundlesFromObject = (key, bundles) => {
138
- for (const bundle of bundles) {
139
- if (locallyDeletedBundleIds.has(bundle.id) || pendingBundlesMap.has(bundle.id)) continue;
140
- bundlesMap.set(bundle.id, {
141
- ...bundle,
142
- _updateJsonKey: key
143
- });
144
- }
145
- };
146
- const loadBundleObject = async (key) => {
147
- const bundles = await loadOptionalObject(key) ?? [];
148
- cacheBundlesFromObject(key, bundles);
149
- return bundles;
150
- };
151
- async function reloadBundles(prefixes = [""]) {
152
- bundlesMap.clear();
153
- pendingBundlesMap.clear();
154
- locallyDeletedBundleIds.clear();
155
- const allBundles = (await mapWithConcurrency((await mapWithConcurrency(prefixes, STORAGE_OPERATION_CONCURRENCY, (prefix) => listObjects(prefix))).flat().filter((key) => /^[^/]+\/(?:ios|android)\/[^/]+\/update\.json$/.test(key)), STORAGE_OPERATION_CONCURRENCY, async (key) => {
156
- return (await loadBundleObject(key)).map((bundle) => ({
157
- ...bundle,
158
- _updateJsonKey: key
159
- }));
160
- })).flat();
161
- for (const bundle of allBundles) bundlesMap.set(bundle.id, bundle);
162
- for (const [id, bundle] of pendingBundlesMap.entries()) bundlesMap.set(id, bundle);
163
- return orderBy(Array.from(bundlesMap.values()), [(v) => v.id], ["desc"]);
164
- }
165
- async function applyTargetVersionMutations(mutations) {
166
- await Promise.all(Array.from(mutations.values()).map(async ({ additions, channel, platform, removals }) => {
167
- const targetKey = `${channel}/${platform}/target-app-versions.json`;
168
- const oldTargetVersions = await loadOptionalObject(targetKey) ?? [];
169
- const newTargetVersions = oldTargetVersions.filter((version) => !removals.has(version) || additions.has(version));
170
- for (const version of additions) if (!newTargetVersions.includes(version)) newTargetVersions.push(version);
171
- if (JSON.stringify(oldTargetVersions) !== JSON.stringify(newTargetVersions)) await uploadObject(targetKey, newTargetVersions);
172
- }));
173
- }
174
- const getAppVersionUpdateInfo = async ({ appVersion, bundleId, channel = "production", cohort, minBundleId, platform }, context) => {
175
- const bundles = (await mapWithConcurrency(filterCompatibleAppVersions(await loadOptionalObject(`${channel}/${platform}/target-app-versions.json`) ?? [], appVersion), STORAGE_OPERATION_CONCURRENCY, async (targetAppVersion) => {
176
- return loadBundleObject(`${channel}/${platform}/${normalizeTargetAppVersion(targetAppVersion) ?? targetAppVersion}/update.json`);
177
- })).flat();
178
- return resolveUpdateInfoFromBundles({
179
- args: {
180
- _updateStrategy: "appVersion",
181
- appVersion,
182
- bundleId,
183
- channel,
184
- cohort,
185
- minBundleId,
186
- platform
187
- },
188
- bundles,
189
- context
190
- });
191
- };
192
- const getFingerprintUpdateInfo = async ({ bundleId, channel = "production", cohort, fingerprintHash, minBundleId, platform }, context) => {
193
- const bundles = await loadBundleObject(`${channel}/${platform}/${fingerprintHash}/update.json`);
194
- return resolveUpdateInfoFromBundles({
195
- args: {
196
- _updateStrategy: "fingerprint",
197
- bundleId,
198
- channel,
199
- cohort,
200
- fingerprintHash,
201
- minBundleId,
202
- platform
203
- },
204
- bundles,
205
- context
206
- });
207
- };
208
- const addAppVersionInvalidationPaths = (pathsToInvalidate, { platform, channel, targetAppVersion }) => {
209
- if (!isExactVersion(targetAppVersion)) {
210
- pathsToInvalidate.add(`${apiBasePath}/app-version/${platform}/*`);
211
- return;
212
- }
213
- const normalizedVersions = getSemverNormalizedVersions(targetAppVersion);
214
- for (const version of normalizedVersions) pathsToInvalidate.add(`${apiBasePath}/app-version/${platform}/${version}/${channel}/*`);
215
- };
216
- const addLookupInvalidationPaths = (pathsToInvalidate, { platform, channel, targetAppVersion, fingerprintHash }) => {
217
- if (fingerprintHash) {
218
- pathsToInvalidate.add(`${apiBasePath}/fingerprint/${platform}/${fingerprintHash}/${channel}/*`);
219
- return;
220
- }
221
- if (targetAppVersion) addAppVersionInvalidationPaths(pathsToInvalidate, {
222
- platform,
223
- channel,
224
- targetAppVersion
225
- });
226
- };
227
- const createPlugin = createDatabasePlugin({
228
- name,
229
- factory: () => ({
230
- supportsCursorPagination: true,
231
- async getBundleById(bundleId) {
232
- if (locallyDeletedBundleIds.has(bundleId)) return null;
233
- const pendingBundle = pendingBundlesMap.get(bundleId);
234
- if (pendingBundle) return removeBundleInternalKeys(pendingBundle);
235
- const bundle = bundlesMap.get(bundleId);
236
- if (bundle) return removeBundleInternalKeys(bundle);
237
- const matchedBundle = (await reloadBundles()).find((item) => item.id === bundleId);
238
- if (!matchedBundle) return null;
239
- return removeBundleInternalKeys(matchedBundle);
240
- },
241
- async getUpdateInfo(args, context) {
242
- if (args._updateStrategy === "appVersion") return getAppVersionUpdateInfo(args, context);
243
- return getFingerprintUpdateInfo(args, context);
244
- },
245
- async getBundles(options) {
246
- const { where, limit, offset, orderBy, cursor } = options;
247
- let allBundles = await loadAllBundlesForManagementFallback(where);
248
- if (where) allBundles = allBundles.filter((bundle) => bundleMatchesQueryWhere(bundle, where));
249
- return paginateBundles({
250
- bundles: allBundles,
251
- limit,
252
- offset,
253
- cursor,
254
- orderBy
255
- });
256
- },
257
- async getChannels() {
258
- const channels = (await listObjects("")).map(getChannelFromUpdateJsonKey).filter((channel) => channel !== null);
259
- return [...new Set(channels)].sort();
260
- },
261
- async commitBundle({ changedSets }) {
262
- if (changedSets.length === 0) return;
263
- for (const { operation, data } of changedSets) if (operation === "insert" || operation === "update" && data.channel !== void 0) validateChannel?.(data.channel);
264
- const changedBundlesByKey = {};
265
- const removalsByKey = {};
266
- const targetVersionRemovalsByKey = {};
267
- const pathsToInvalidate = /* @__PURE__ */ new Set();
268
- const targetVersionMutations = /* @__PURE__ */ new Map();
269
- for (const { operation, data } of changedSets) {
270
- if (operation === "insert") {
271
- const target = resolveStorageTarget(data);
272
- const key = `${data.channel}/${data.platform}/${target}/update.json`;
273
- const bundleWithKey = {
274
- ...data,
275
- _updateJsonKey: key
276
- };
277
- locallyDeletedBundleIds.delete(data.id);
278
- bundlesMap.set(data.id, bundleWithKey);
279
- pendingBundlesMap.set(data.id, bundleWithKey);
280
- changedBundlesByKey[key] = changedBundlesByKey[key] || [];
281
- changedBundlesByKey[key].push(removeBundleInternalKeys(bundleWithKey));
282
- addTargetVersionAddition(targetVersionMutations, data);
283
- addLookupInvalidationPaths(pathsToInvalidate, data);
284
- continue;
285
- }
286
- if (operation === "delete") {
287
- let bundle = pendingBundlesMap.get(data.id);
288
- if (!bundle) bundle = bundlesMap.get(data.id);
289
- if (!bundle) throw new Error("Bundle to delete not found");
290
- bundlesMap.delete(data.id);
291
- pendingBundlesMap.delete(data.id);
292
- locallyDeletedBundleIds.add(data.id);
293
- const key = bundle._updateJsonKey;
294
- removalsByKey[key] = removalsByKey[key] || [];
295
- removalsByKey[key].push(bundle.id);
296
- targetVersionRemovalsByKey[key] = targetVersionRemovalsByKey[key] || [];
297
- targetVersionRemovalsByKey[key].push(bundle);
298
- addLookupInvalidationPaths(pathsToInvalidate, bundle);
299
- continue;
300
- }
301
- let bundle = pendingBundlesMap.get(data.id);
302
- if (!bundle) bundle = bundlesMap.get(data.id);
303
- if (!bundle) throw new Error("targetBundleId not found");
304
- if (operation === "update") {
305
- const updatedBundle = {
306
- ...bundle,
307
- ...data
308
- };
309
- const newKey = `${updatedBundle.channel}/${updatedBundle.platform}/${resolveStorageTarget(updatedBundle)}/update.json`;
310
- if (newKey !== bundle._updateJsonKey) {
311
- const oldKey = bundle._updateJsonKey;
312
- removalsByKey[oldKey] = removalsByKey[oldKey] || [];
313
- removalsByKey[oldKey].push(bundle.id);
314
- targetVersionRemovalsByKey[oldKey] = targetVersionRemovalsByKey[oldKey] || [];
315
- targetVersionRemovalsByKey[oldKey].push(bundle);
316
- changedBundlesByKey[newKey] = changedBundlesByKey[newKey] || [];
317
- updatedBundle._oldUpdateJsonKey = oldKey;
318
- updatedBundle._updateJsonKey = newKey;
319
- bundlesMap.set(data.id, updatedBundle);
320
- pendingBundlesMap.set(data.id, updatedBundle);
321
- locallyDeletedBundleIds.delete(data.id);
322
- changedBundlesByKey[newKey].push(removeBundleInternalKeys(updatedBundle));
323
- const oldChannel = bundle.channel;
324
- const nextChannel = updatedBundle.channel;
325
- if (oldChannel !== nextChannel) {
326
- addLookupInvalidationPaths(pathsToInvalidate, bundle);
327
- if (bundle.targetAppVersion && !bundle.fingerprintHash) addLookupInvalidationPaths(pathsToInvalidate, {
328
- ...bundle,
329
- channel: nextChannel
330
- });
331
- }
332
- addTargetVersionAddition(targetVersionMutations, updatedBundle);
333
- addLookupInvalidationPaths(pathsToInvalidate, updatedBundle);
334
- if (bundle.targetAppVersion && bundle.targetAppVersion !== updatedBundle.targetAppVersion) addLookupInvalidationPaths(pathsToInvalidate, bundle);
335
- continue;
336
- }
337
- const currentKey = bundle._updateJsonKey;
338
- bundlesMap.set(data.id, updatedBundle);
339
- pendingBundlesMap.set(data.id, updatedBundle);
340
- locallyDeletedBundleIds.delete(data.id);
341
- changedBundlesByKey[currentKey] = changedBundlesByKey[currentKey] || [];
342
- changedBundlesByKey[currentKey].push(removeBundleInternalKeys(updatedBundle));
343
- addLookupInvalidationPaths(pathsToInvalidate, updatedBundle);
344
- addTargetVersionAddition(targetVersionMutations, updatedBundle);
345
- if (bundle.targetAppVersion && bundle.targetAppVersion !== updatedBundle.targetAppVersion) addLookupInvalidationPaths(pathsToInvalidate, bundle);
346
- }
347
- }
348
- await forEachWithConcurrency(Object.keys(removalsByKey), STORAGE_OPERATION_CONCURRENCY, async (oldKey) => {
349
- const updatedBundles = (await loadOptionalObject(oldKey) ?? []).filter((b) => !removalsByKey[oldKey].includes(b.id));
350
- updatedBundles.sort((a, b) => b.id.localeCompare(a.id));
351
- if (updatedBundles.length === 0) {
352
- await deleteObject(oldKey);
353
- for (const removedBundle of targetVersionRemovalsByKey[oldKey] ?? []) addTargetVersionRemoval(targetVersionMutations, removedBundle);
354
- } else await uploadObject(oldKey, updatedBundles);
355
- });
356
- await forEachWithConcurrency(Object.keys(changedBundlesByKey), STORAGE_OPERATION_CONCURRENCY, async (key) => {
357
- const currentBundles = await loadOptionalObject(key) ?? [];
358
- const pureBundles = changedBundlesByKey[key].map((bundle) => bundle);
359
- for (const changedBundle of pureBundles) {
360
- const index = currentBundles.findIndex((b) => b.id === changedBundle.id);
361
- if (index >= 0) currentBundles[index] = changedBundle;
362
- else currentBundles.push(changedBundle);
363
- }
364
- currentBundles.sort((a, b) => b.id.localeCompare(a.id));
365
- await uploadObject(key, currentBundles);
366
- });
367
- if (targetVersionMutations.size > 0) await applyTargetVersionMutations(targetVersionMutations);
368
- const encondedPaths = /* @__PURE__ */ new Set();
369
- for (const path of pathsToInvalidate) encondedPaths.add(encodeURI(path));
370
- await invalidatePaths(Array.from(encondedPaths));
371
- pendingBundlesMap.clear();
372
- }
373
- })
374
- })({}, hooks);
375
- return () => {
376
- return createPlugin();
377
- };
378
- };
379
- };
380
- //#endregion
381
- export { createBlobDatabasePlugin };
@@ -1,12 +0,0 @@
1
- //#region src/legacyAssetStorageLayout.ts
2
- /**
3
- * @internal
4
- *
5
- * Legacy manifest assets were stored below each bundle's `/files` directory
6
- * using their manifest-relative path. Keep all old-layout path decisions here
7
- * so support can be removed by deleting this module and the entrypoint branch
8
- * that imports it.
9
- */
10
- const getLegacyManifestAssetStoragePath = ({ assetPath }) => assetPath;
11
- //#endregion
12
- exports.getLegacyManifestAssetStoragePath = getLegacyManifestAssetStoragePath;
@@ -1,12 +0,0 @@
1
- //#region src/legacyAssetStorageLayout.ts
2
- /**
3
- * @internal
4
- *
5
- * Legacy manifest assets were stored below each bundle's `/files` directory
6
- * using their manifest-relative path. Keep all old-layout path decisions here
7
- * so support can be removed by deleting this module and the entrypoint branch
8
- * that imports it.
9
- */
10
- const getLegacyManifestAssetStoragePath = ({ assetPath }) => assetPath;
11
- //#endregion
12
- export { getLegacyManifestAssetStoragePath };
@@ -1,26 +0,0 @@
1
- const require_bundleUnitOfWork = require("./bundleUnitOfWork.cjs");
2
- const require_bundleUnitOfWorkStore = require("./bundleUnitOfWorkStore.cjs");
3
- //#region src/requestUpdateBundleState.ts
4
- const toBundleSeeds = (seeds) => seeds.filter((seed) => !!seed);
5
- const seedRequestUpdateBundles = (context, seeds) => {
6
- const unitOfWork = require_bundleUnitOfWorkStore.getRequestBundleUnitOfWork(context);
7
- if (!unitOfWork) return;
8
- const nextSeeds = toBundleSeeds(seeds);
9
- if (nextSeeds.length === 0) return;
10
- unitOfWork.seed(nextSeeds);
11
- };
12
- const getRequestUpdateBundleSeeds = (context) => {
13
- return require_bundleUnitOfWorkStore.getRequestBundleUnitOfWork(context)?.seededBundles() ?? [];
14
- };
15
- const createRequestUpdateBundleResolver = (context) => {
16
- const unitOfWork = require_bundleUnitOfWorkStore.getRequestBundleUnitOfWork(context) ?? new require_bundleUnitOfWork.BundleUnitOfWork();
17
- return {
18
- hasSeededBundles: () => unitOfWork.hasSeeds(),
19
- peek: (bundleId) => unitOfWork.peek(bundleId),
20
- getById: (bundleId, loadBundleById) => unitOfWork.getById(bundleId, loadBundleById)
21
- };
22
- };
23
- //#endregion
24
- exports.createRequestUpdateBundleResolver = createRequestUpdateBundleResolver;
25
- exports.getRequestUpdateBundleSeeds = getRequestUpdateBundleSeeds;
26
- exports.seedRequestUpdateBundles = seedRequestUpdateBundles;
@@ -1,12 +0,0 @@
1
- import { Bundle, HotUpdaterContext } from "./types/index.cjs";
2
-
3
- //#region src/requestUpdateBundleState.d.ts
4
- interface RequestUpdateBundleResolver {
5
- readonly hasSeededBundles: () => boolean;
6
- readonly peek: (bundleId: string) => Bundle | null;
7
- readonly getById: (bundleId: string, loadBundleById: () => Promise<Bundle | null>) => Promise<Bundle | null>;
8
- }
9
- declare const getRequestUpdateBundleSeeds: <TContext = unknown>(context: HotUpdaterContext<TContext> | undefined) => readonly Bundle[];
10
- declare const createRequestUpdateBundleResolver: <TContext = unknown>(context: HotUpdaterContext<TContext> | undefined) => RequestUpdateBundleResolver;
11
- //#endregion
12
- export { createRequestUpdateBundleResolver, getRequestUpdateBundleSeeds };
@@ -1,12 +0,0 @@
1
- import { Bundle, HotUpdaterContext } from "./types/index.mjs";
2
-
3
- //#region src/requestUpdateBundleState.d.ts
4
- interface RequestUpdateBundleResolver {
5
- readonly hasSeededBundles: () => boolean;
6
- readonly peek: (bundleId: string) => Bundle | null;
7
- readonly getById: (bundleId: string, loadBundleById: () => Promise<Bundle | null>) => Promise<Bundle | null>;
8
- }
9
- declare const getRequestUpdateBundleSeeds: <TContext = unknown>(context: HotUpdaterContext<TContext> | undefined) => readonly Bundle[];
10
- declare const createRequestUpdateBundleResolver: <TContext = unknown>(context: HotUpdaterContext<TContext> | undefined) => RequestUpdateBundleResolver;
11
- //#endregion
12
- export { createRequestUpdateBundleResolver, getRequestUpdateBundleSeeds };
@@ -1,24 +0,0 @@
1
- import { BundleUnitOfWork } from "./bundleUnitOfWork.mjs";
2
- import { getRequestBundleUnitOfWork } from "./bundleUnitOfWorkStore.mjs";
3
- //#region src/requestUpdateBundleState.ts
4
- const toBundleSeeds = (seeds) => seeds.filter((seed) => !!seed);
5
- const seedRequestUpdateBundles = (context, seeds) => {
6
- const unitOfWork = getRequestBundleUnitOfWork(context);
7
- if (!unitOfWork) return;
8
- const nextSeeds = toBundleSeeds(seeds);
9
- if (nextSeeds.length === 0) return;
10
- unitOfWork.seed(nextSeeds);
11
- };
12
- const getRequestUpdateBundleSeeds = (context) => {
13
- return getRequestBundleUnitOfWork(context)?.seededBundles() ?? [];
14
- };
15
- const createRequestUpdateBundleResolver = (context) => {
16
- const unitOfWork = getRequestBundleUnitOfWork(context) ?? new BundleUnitOfWork();
17
- return {
18
- hasSeededBundles: () => unitOfWork.hasSeeds(),
19
- peek: (bundleId) => unitOfWork.peek(bundleId),
20
- getById: (bundleId, loadBundleById) => unitOfWork.getById(bundleId, loadBundleById)
21
- };
22
- };
23
- //#endregion
24
- export { createRequestUpdateBundleResolver, getRequestUpdateBundleSeeds, seedRequestUpdateBundles };
@@ -1,14 +0,0 @@
1
- require("./_virtual/_rolldown/runtime.cjs");
2
- const require_requestUpdateBundleState = require("./requestUpdateBundleState.cjs");
3
- let _hot_updater_core = require("@hot-updater/core");
4
- let _hot_updater_js = require("@hot-updater/js");
5
- //#region src/resolveUpdateInfoFromBundles.ts
6
- const findSeedBundle = (bundles, bundleId) => bundles.find((bundle) => bundle.id === bundleId);
7
- const resolveUpdateInfoFromBundles = async ({ args, bundles, context }) => {
8
- const info = await (0, _hot_updater_js.getUpdateInfo)(bundles, args);
9
- if (!info) return null;
10
- require_requestUpdateBundleState.seedRequestUpdateBundles(context, [findSeedBundle(bundles, info.id), args.bundleId === _hot_updater_core.NIL_UUID ? null : findSeedBundle(bundles, args.bundleId)]);
11
- return info;
12
- };
13
- //#endregion
14
- exports.resolveUpdateInfoFromBundles = resolveUpdateInfoFromBundles;
@@ -1,16 +0,0 @@
1
- import { Bundle as Bundle$1, HotUpdaterContext } from "./types/index.cjs";
2
- import { GetBundlesArgs, UpdateInfo } from "@hot-updater/core";
3
-
4
- //#region src/resolveUpdateInfoFromBundles.d.ts
5
- interface ResolveUpdateInfoFromBundlesOptions<TContext = unknown> {
6
- readonly args: GetBundlesArgs;
7
- readonly bundles: Bundle$1[];
8
- readonly context?: HotUpdaterContext<TContext>;
9
- }
10
- declare const resolveUpdateInfoFromBundles: <TContext = unknown>({
11
- args,
12
- bundles,
13
- context
14
- }: ResolveUpdateInfoFromBundlesOptions<TContext>) => Promise<UpdateInfo | null>;
15
- //#endregion
16
- export { ResolveUpdateInfoFromBundlesOptions, resolveUpdateInfoFromBundles };
@@ -1,16 +0,0 @@
1
- import { Bundle as Bundle$1, HotUpdaterContext } from "./types/index.mjs";
2
- import { GetBundlesArgs, UpdateInfo } from "@hot-updater/core";
3
-
4
- //#region src/resolveUpdateInfoFromBundles.d.ts
5
- interface ResolveUpdateInfoFromBundlesOptions<TContext = unknown> {
6
- readonly args: GetBundlesArgs;
7
- readonly bundles: Bundle$1[];
8
- readonly context?: HotUpdaterContext<TContext>;
9
- }
10
- declare const resolveUpdateInfoFromBundles: <TContext = unknown>({
11
- args,
12
- bundles,
13
- context
14
- }: ResolveUpdateInfoFromBundlesOptions<TContext>) => Promise<UpdateInfo | null>;
15
- //#endregion
16
- export { ResolveUpdateInfoFromBundlesOptions, resolveUpdateInfoFromBundles };
@@ -1,13 +0,0 @@
1
- import { seedRequestUpdateBundles } from "./requestUpdateBundleState.mjs";
2
- import { NIL_UUID } from "@hot-updater/core";
3
- import { getUpdateInfo } from "@hot-updater/js";
4
- //#region src/resolveUpdateInfoFromBundles.ts
5
- const findSeedBundle = (bundles, bundleId) => bundles.find((bundle) => bundle.id === bundleId);
6
- const resolveUpdateInfoFromBundles = async ({ args, bundles, context }) => {
7
- const info = await getUpdateInfo(bundles, args);
8
- if (!info) return null;
9
- seedRequestUpdateBundles(context, [findSeedBundle(bundles, info.id), args.bundleId === NIL_UUID ? null : findSeedBundle(bundles, args.bundleId)]);
10
- return info;
11
- };
12
- //#endregion
13
- export { resolveUpdateInfoFromBundles };
@@ -1,15 +0,0 @@
1
- //#region src/storageProfile.ts
2
- const createMissingProfileError = (plugin, profile) => /* @__PURE__ */ new Error(`${plugin.name} does not implement the ${profile} storage profile for protocol "${plugin.supportedProtocol}".`);
3
- const isNodeStoragePlugin = (plugin) => Boolean(plugin.profiles.node);
4
- const isRuntimeStoragePlugin = (plugin) => Boolean(plugin.profiles.runtime);
5
- function assertNodeStoragePlugin(plugin) {
6
- if (!isNodeStoragePlugin(plugin)) throw createMissingProfileError(plugin, "node");
7
- }
8
- function assertRuntimeStoragePlugin(plugin) {
9
- if (!isRuntimeStoragePlugin(plugin)) throw createMissingProfileError(plugin, "runtime");
10
- }
11
- //#endregion
12
- exports.assertNodeStoragePlugin = assertNodeStoragePlugin;
13
- exports.assertRuntimeStoragePlugin = assertRuntimeStoragePlugin;
14
- exports.isNodeStoragePlugin = isNodeStoragePlugin;
15
- exports.isRuntimeStoragePlugin = isRuntimeStoragePlugin;
@@ -1,9 +0,0 @@
1
- import { NodeStoragePlugin, RuntimeStoragePlugin, StoragePlugin } from "./types/index.cjs";
2
-
3
- //#region src/storageProfile.d.ts
4
- declare const isNodeStoragePlugin: <TContext = unknown>(plugin: StoragePlugin<TContext>) => plugin is NodeStoragePlugin<TContext>;
5
- declare const isRuntimeStoragePlugin: <TContext = unknown>(plugin: StoragePlugin<TContext>) => plugin is RuntimeStoragePlugin<TContext>;
6
- declare function assertNodeStoragePlugin<TContext = unknown>(plugin: StoragePlugin<TContext>): asserts plugin is NodeStoragePlugin<TContext>;
7
- declare function assertRuntimeStoragePlugin<TContext = unknown>(plugin: StoragePlugin<TContext>): asserts plugin is RuntimeStoragePlugin<TContext>;
8
- //#endregion
9
- export { assertNodeStoragePlugin, assertRuntimeStoragePlugin, isNodeStoragePlugin, isRuntimeStoragePlugin };
@@ -1,9 +0,0 @@
1
- import { NodeStoragePlugin, RuntimeStoragePlugin, StoragePlugin } from "./types/index.mjs";
2
-
3
- //#region src/storageProfile.d.ts
4
- declare const isNodeStoragePlugin: <TContext = unknown>(plugin: StoragePlugin<TContext>) => plugin is NodeStoragePlugin<TContext>;
5
- declare const isRuntimeStoragePlugin: <TContext = unknown>(plugin: StoragePlugin<TContext>) => plugin is RuntimeStoragePlugin<TContext>;
6
- declare function assertNodeStoragePlugin<TContext = unknown>(plugin: StoragePlugin<TContext>): asserts plugin is NodeStoragePlugin<TContext>;
7
- declare function assertRuntimeStoragePlugin<TContext = unknown>(plugin: StoragePlugin<TContext>): asserts plugin is RuntimeStoragePlugin<TContext>;
8
- //#endregion
9
- export { assertNodeStoragePlugin, assertRuntimeStoragePlugin, isNodeStoragePlugin, isRuntimeStoragePlugin };
@@ -1,12 +0,0 @@
1
- //#region src/storageProfile.ts
2
- const createMissingProfileError = (plugin, profile) => /* @__PURE__ */ new Error(`${plugin.name} does not implement the ${profile} storage profile for protocol "${plugin.supportedProtocol}".`);
3
- const isNodeStoragePlugin = (plugin) => Boolean(plugin.profiles.node);
4
- const isRuntimeStoragePlugin = (plugin) => Boolean(plugin.profiles.runtime);
5
- function assertNodeStoragePlugin(plugin) {
6
- if (!isNodeStoragePlugin(plugin)) throw createMissingProfileError(plugin, "node");
7
- }
8
- function assertRuntimeStoragePlugin(plugin) {
9
- if (!isRuntimeStoragePlugin(plugin)) throw createMissingProfileError(plugin, "runtime");
10
- }
11
- //#endregion
12
- export { assertNodeStoragePlugin, assertRuntimeStoragePlugin, isNodeStoragePlugin, isRuntimeStoragePlugin };