@hot-updater/plugin-core 0.31.4 → 0.33.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 (35) hide show
  1. package/dist/assetStorageLayout.cjs +34 -0
  2. package/dist/assetStorageLayout.d.cts +31 -0
  3. package/dist/assetStorageLayout.d.mts +31 -0
  4. package/dist/assetStorageLayout.mjs +30 -0
  5. package/dist/compressionFormat.cjs +2 -2
  6. package/dist/contentAddressedAssets.cjs +7 -0
  7. package/dist/contentAddressedAssets.d.cts +10 -0
  8. package/dist/contentAddressedAssets.d.mts +10 -0
  9. package/dist/contentAddressedAssets.mjs +7 -0
  10. package/dist/createBlobDatabasePlugin.cjs +155 -55
  11. package/dist/createBlobDatabasePlugin.d.cts +1 -0
  12. package/dist/createBlobDatabasePlugin.d.mts +1 -0
  13. package/dist/createBlobDatabasePlugin.mjs +154 -54
  14. package/dist/createDatabasePluginGetUpdateInfo.cjs +11 -3
  15. package/dist/createDatabasePluginGetUpdateInfo.mjs +11 -3
  16. package/dist/createStoragePlugin.cjs +3 -0
  17. package/dist/createStoragePlugin.mjs +3 -0
  18. package/dist/index.cjs +12 -0
  19. package/dist/index.d.cts +6 -2
  20. package/dist/index.d.mts +6 -2
  21. package/dist/index.mjs +5 -1
  22. package/dist/legacyAssetStorageLayout.cjs +12 -0
  23. package/dist/legacyAssetStorageLayout.mjs +12 -0
  24. package/dist/requestUpdateBundleState.cjs +20 -0
  25. package/dist/requestUpdateBundleState.d.cts +6 -0
  26. package/dist/requestUpdateBundleState.d.mts +6 -0
  27. package/dist/requestUpdateBundleState.mjs +19 -0
  28. package/dist/resolveUpdateInfoFromBundles.cjs +14 -0
  29. package/dist/resolveUpdateInfoFromBundles.d.cts +16 -0
  30. package/dist/resolveUpdateInfoFromBundles.d.mts +16 -0
  31. package/dist/resolveUpdateInfoFromBundles.mjs +13 -0
  32. package/dist/semverSatisfies.cjs +1 -1
  33. package/dist/types/index.d.cts +47 -1
  34. package/dist/types/index.d.mts +47 -1
  35. package/package.json +4 -4
@@ -0,0 +1,6 @@
1
+ import { Bundle, HotUpdaterContext } from "./types/index.mjs";
2
+
3
+ //#region src/requestUpdateBundleState.d.ts
4
+ declare const getRequestUpdateBundleSeeds: <TContext = unknown>(context: HotUpdaterContext<TContext> | undefined) => readonly Bundle[];
5
+ //#endregion
6
+ export { getRequestUpdateBundleSeeds };
@@ -0,0 +1,19 @@
1
+ //#region src/requestUpdateBundleState.ts
2
+ const requestUpdateBundleSeeds = /* @__PURE__ */ new WeakMap();
3
+ const isWeakMapKey = (value) => typeof value === "object" && value !== null || typeof value === "function";
4
+ const toBundleSeeds = (seeds) => seeds.filter((seed) => !!seed);
5
+ const seedRequestUpdateBundles = (context, seeds) => {
6
+ if (!isWeakMapKey(context)) return;
7
+ const nextSeeds = toBundleSeeds(seeds);
8
+ if (nextSeeds.length === 0) return;
9
+ const bundlesById = /* @__PURE__ */ new Map();
10
+ for (const seed of requestUpdateBundleSeeds.get(context) ?? []) bundlesById.set(seed.id, seed);
11
+ for (const seed of nextSeeds) bundlesById.set(seed.id, seed);
12
+ requestUpdateBundleSeeds.set(context, [...bundlesById.values()]);
13
+ };
14
+ const getRequestUpdateBundleSeeds = (context) => {
15
+ if (!isWeakMapKey(context)) return [];
16
+ return requestUpdateBundleSeeds.get(context) ?? [];
17
+ };
18
+ //#endregion
19
+ export { getRequestUpdateBundleSeeds, seedRequestUpdateBundles };
@@ -0,0 +1,14 @@
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;
@@ -0,0 +1,16 @@
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 };
@@ -0,0 +1,16 @@
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 };
@@ -0,0 +1,13 @@
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,6 +1,6 @@
1
1
  const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
2
2
  let semver = require("semver");
3
- semver = require_runtime.__toESM(semver, 1);
3
+ semver = require_runtime.__toESM(semver);
4
4
  //#region src/semverSatisfies.ts
5
5
  const semverSatisfies = (targetAppVersion, currentVersion) => {
6
6
  const currentCoerce = semver.default.coerce(currentVersion);
@@ -69,6 +69,28 @@ interface DatabaseBundleQueryOptions {
69
69
  cursor?: DatabaseBundleCursor;
70
70
  orderBy?: DatabaseBundleQueryOrder;
71
71
  }
72
+ interface BundleIndexHealth {
73
+ status: "ok" | "missing" | "stale";
74
+ canonicalBundles: number;
75
+ indexedBundles: number;
76
+ missingBundles: number;
77
+ extraBundles: number;
78
+ missingBundleIds: string[];
79
+ extraBundleIds: string[];
80
+ }
81
+ interface BundleIndexRepairResult {
82
+ scannedBundles: number;
83
+ indexedBundles: number;
84
+ pagesWritten: number;
85
+ scopesWritten: number;
86
+ }
87
+ interface BundleIndexDiagnostics<TContext = unknown> {
88
+ check: (context?: HotUpdaterContext<TContext>) => Promise<BundleIndexHealth>;
89
+ repair?: (context?: HotUpdaterContext<TContext>) => Promise<BundleIndexRepairResult>;
90
+ }
91
+ interface DatabaseDiagnostics<TContext = unknown> {
92
+ bundleIndex?: BundleIndexDiagnostics<TContext>;
93
+ }
72
94
  interface BuildPluginConfig {
73
95
  outDir?: string;
74
96
  }
@@ -80,6 +102,7 @@ interface DatabasePlugin<TContext = unknown> {
80
102
  updateBundle: (targetBundleId: string, newBundle: Partial<Bundle>, context?: HotUpdaterContext<TContext>) => Promise<void>;
81
103
  appendBundle: (insertBundle: Bundle, context?: HotUpdaterContext<TContext>) => Promise<void>;
82
104
  commitBundle: (context?: HotUpdaterContext<TContext>) => Promise<void>;
105
+ diagnostics?: DatabaseDiagnostics<TContext>;
83
106
  onUnmount?: () => Promise<void>;
84
107
  name: string;
85
108
  deleteBundle: (deleteBundle: Bundle, context?: HotUpdaterContext<TContext>) => Promise<void>;
@@ -232,9 +255,19 @@ interface PlatformConfig {
232
255
  * Android platform configuration.
233
256
  */
234
257
  android?: {
258
+ /**
259
+ * Android manifest paths.
260
+ *
261
+ * @default all AndroidManifest.xml files in the android directory
262
+ * @example ["android/app/src/main/AndroidManifest.xml"]
263
+ */
264
+ androidManifestPaths?: string[];
235
265
  /**
236
266
  * Android string resource paths.
237
267
  *
268
+ * @deprecated Android Hot Updater config is stored in AndroidManifest.xml.
269
+ * This remains supported as a legacy read fallback.
270
+ *
238
271
  * @default all strings.xml files in the android directory
239
272
  * @example ["android/app/src/main/res/values/strings.xml"]
240
273
  */
@@ -273,6 +306,12 @@ interface NodeStorageProfile {
273
306
  upload: (key: string, filePath: string) => Promise<{
274
307
  storageUri: string;
275
308
  }>;
309
+ /**
310
+ * Returns true when the object can be safely reused by deploy without
311
+ * uploading it again. Providers may validate more than physical existence
312
+ * when runtime access needs an additional readiness check.
313
+ */
314
+ exists: (storageUri: string) => Promise<boolean>;
276
315
  delete: (storageUri: string) => Promise<void>;
277
316
  downloadFile: (storageUri: string, filePath: string) => Promise<void>;
278
317
  }
@@ -363,6 +402,13 @@ type SigningConfig = {
363
402
  privateKeyPath: string;
364
403
  };
365
404
  type ConfigInput = {
405
+ /**
406
+ * @hidden
407
+ * Local cache directory used by Hot Updater CLI. Set to `null` to disable.
408
+ *
409
+ * @default "node_modules/.hot-updater"
410
+ */
411
+ cacheDir?: string | null;
366
412
  /**
367
413
  * The channel used when building the native app.
368
414
  * Used to replace __HOT_UPDATER_CHANNEL at build time.
@@ -481,4 +527,4 @@ interface NativeBuildOptions {
481
527
  scheme?: string;
482
528
  }
483
529
  //#endregion
484
- export { type AppVersionGetBundlesArgs$1 as AppVersionGetBundlesArgs, ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, type Bundle$1 as Bundle, ConfigInput, DatabaseBundleCursor, DatabaseBundleIdFilter, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, DatabasePlugin, DatabasePluginHooks, type FingerprintGetBundlesArgs$1 as FingerprintGetBundlesArgs, type GetBundlesArgs$1 as GetBundlesArgs, HotUpdaterContext, IosBuildDestination, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, NodeStoragePlugin, NodeStorageProfile, Paginated, PaginatedResult, PaginationInfo, type Platform$1 as Platform, PlatformConfig, RequestEnvContext, RuntimeStoragePlugin, RuntimeStorageProfile, SigningConfig, StoragePlugin, StoragePluginHooks, StoragePluginProfiles, StorageResolveContext, UniversalStoragePlugin, type UpdateInfo$1 as UpdateInfo, supportedIosPlatforms };
530
+ export { type AppVersionGetBundlesArgs$1 as AppVersionGetBundlesArgs, ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, type Bundle$1 as Bundle, BundleIndexDiagnostics, BundleIndexHealth, BundleIndexRepairResult, ConfigInput, DatabaseBundleCursor, DatabaseBundleIdFilter, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, DatabaseDiagnostics, DatabasePlugin, DatabasePluginHooks, type FingerprintGetBundlesArgs$1 as FingerprintGetBundlesArgs, type GetBundlesArgs$1 as GetBundlesArgs, HotUpdaterContext, IosBuildDestination, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, NodeStoragePlugin, NodeStorageProfile, Paginated, PaginatedResult, PaginationInfo, type Platform$1 as Platform, PlatformConfig, RequestEnvContext, RuntimeStoragePlugin, RuntimeStorageProfile, SigningConfig, StoragePlugin, StoragePluginHooks, StoragePluginProfiles, StorageResolveContext, UniversalStoragePlugin, type UpdateInfo$1 as UpdateInfo, supportedIosPlatforms };
@@ -69,6 +69,28 @@ interface DatabaseBundleQueryOptions {
69
69
  cursor?: DatabaseBundleCursor;
70
70
  orderBy?: DatabaseBundleQueryOrder;
71
71
  }
72
+ interface BundleIndexHealth {
73
+ status: "ok" | "missing" | "stale";
74
+ canonicalBundles: number;
75
+ indexedBundles: number;
76
+ missingBundles: number;
77
+ extraBundles: number;
78
+ missingBundleIds: string[];
79
+ extraBundleIds: string[];
80
+ }
81
+ interface BundleIndexRepairResult {
82
+ scannedBundles: number;
83
+ indexedBundles: number;
84
+ pagesWritten: number;
85
+ scopesWritten: number;
86
+ }
87
+ interface BundleIndexDiagnostics<TContext = unknown> {
88
+ check: (context?: HotUpdaterContext<TContext>) => Promise<BundleIndexHealth>;
89
+ repair?: (context?: HotUpdaterContext<TContext>) => Promise<BundleIndexRepairResult>;
90
+ }
91
+ interface DatabaseDiagnostics<TContext = unknown> {
92
+ bundleIndex?: BundleIndexDiagnostics<TContext>;
93
+ }
72
94
  interface BuildPluginConfig {
73
95
  outDir?: string;
74
96
  }
@@ -80,6 +102,7 @@ interface DatabasePlugin<TContext = unknown> {
80
102
  updateBundle: (targetBundleId: string, newBundle: Partial<Bundle>, context?: HotUpdaterContext<TContext>) => Promise<void>;
81
103
  appendBundle: (insertBundle: Bundle, context?: HotUpdaterContext<TContext>) => Promise<void>;
82
104
  commitBundle: (context?: HotUpdaterContext<TContext>) => Promise<void>;
105
+ diagnostics?: DatabaseDiagnostics<TContext>;
83
106
  onUnmount?: () => Promise<void>;
84
107
  name: string;
85
108
  deleteBundle: (deleteBundle: Bundle, context?: HotUpdaterContext<TContext>) => Promise<void>;
@@ -232,9 +255,19 @@ interface PlatformConfig {
232
255
  * Android platform configuration.
233
256
  */
234
257
  android?: {
258
+ /**
259
+ * Android manifest paths.
260
+ *
261
+ * @default all AndroidManifest.xml files in the android directory
262
+ * @example ["android/app/src/main/AndroidManifest.xml"]
263
+ */
264
+ androidManifestPaths?: string[];
235
265
  /**
236
266
  * Android string resource paths.
237
267
  *
268
+ * @deprecated Android Hot Updater config is stored in AndroidManifest.xml.
269
+ * This remains supported as a legacy read fallback.
270
+ *
238
271
  * @default all strings.xml files in the android directory
239
272
  * @example ["android/app/src/main/res/values/strings.xml"]
240
273
  */
@@ -273,6 +306,12 @@ interface NodeStorageProfile {
273
306
  upload: (key: string, filePath: string) => Promise<{
274
307
  storageUri: string;
275
308
  }>;
309
+ /**
310
+ * Returns true when the object can be safely reused by deploy without
311
+ * uploading it again. Providers may validate more than physical existence
312
+ * when runtime access needs an additional readiness check.
313
+ */
314
+ exists: (storageUri: string) => Promise<boolean>;
276
315
  delete: (storageUri: string) => Promise<void>;
277
316
  downloadFile: (storageUri: string, filePath: string) => Promise<void>;
278
317
  }
@@ -363,6 +402,13 @@ type SigningConfig = {
363
402
  privateKeyPath: string;
364
403
  };
365
404
  type ConfigInput = {
405
+ /**
406
+ * @hidden
407
+ * Local cache directory used by Hot Updater CLI. Set to `null` to disable.
408
+ *
409
+ * @default "node_modules/.hot-updater"
410
+ */
411
+ cacheDir?: string | null;
366
412
  /**
367
413
  * The channel used when building the native app.
368
414
  * Used to replace __HOT_UPDATER_CHANNEL at build time.
@@ -481,4 +527,4 @@ interface NativeBuildOptions {
481
527
  scheme?: string;
482
528
  }
483
529
  //#endregion
484
- export { type AppVersionGetBundlesArgs$1 as AppVersionGetBundlesArgs, ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, type Bundle$1 as Bundle, ConfigInput, DatabaseBundleCursor, DatabaseBundleIdFilter, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, DatabasePlugin, DatabasePluginHooks, type FingerprintGetBundlesArgs$1 as FingerprintGetBundlesArgs, type GetBundlesArgs$1 as GetBundlesArgs, HotUpdaterContext, IosBuildDestination, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, NodeStoragePlugin, NodeStorageProfile, Paginated, PaginatedResult, PaginationInfo, type Platform$1 as Platform, PlatformConfig, RequestEnvContext, RuntimeStoragePlugin, RuntimeStorageProfile, SigningConfig, StoragePlugin, StoragePluginHooks, StoragePluginProfiles, StorageResolveContext, UniversalStoragePlugin, type UpdateInfo$1 as UpdateInfo, supportedIosPlatforms };
530
+ export { type AppVersionGetBundlesArgs$1 as AppVersionGetBundlesArgs, ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, type Bundle$1 as Bundle, BundleIndexDiagnostics, BundleIndexHealth, BundleIndexRepairResult, ConfigInput, DatabaseBundleCursor, DatabaseBundleIdFilter, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, DatabaseDiagnostics, DatabasePlugin, DatabasePluginHooks, type FingerprintGetBundlesArgs$1 as FingerprintGetBundlesArgs, type GetBundlesArgs$1 as GetBundlesArgs, HotUpdaterContext, IosBuildDestination, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, NodeStoragePlugin, NodeStorageProfile, Paginated, PaginatedResult, PaginationInfo, type Platform$1 as Platform, PlatformConfig, RequestEnvContext, RuntimeStoragePlugin, RuntimeStorageProfile, SigningConfig, StoragePlugin, StoragePluginHooks, StoragePluginProfiles, StorageResolveContext, UniversalStoragePlugin, type UpdateInfo$1 as UpdateInfo, supportedIosPlatforms };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hot-updater/plugin-core",
3
- "version": "0.31.4",
3
+ "version": "0.33.0",
4
4
  "type": "module",
5
5
  "description": "React Native OTA solution for self-hosted",
6
6
  "sideEffects": false,
@@ -42,14 +42,14 @@
42
42
  "es-toolkit": "^1.32.0",
43
43
  "mime": "^4.0.4",
44
44
  "semver": "^7.7.2",
45
- "@hot-updater/core": "0.31.4",
46
- "@hot-updater/js": "0.31.4"
45
+ "@hot-updater/js": "0.33.0",
46
+ "@hot-updater/core": "0.33.0"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/node": "^20",
50
50
  "@types/semver": "^7.5.8",
51
51
  "typescript": "6.0.2",
52
- "@hot-updater/test-utils": "0.31.4"
52
+ "@hot-updater/test-utils": "0.33.0"
53
53
  },
54
54
  "scripts": {
55
55
  "build": "tsdown",