react-native-3rddigital-appupdate 1.0.14 → 1.0.17

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/README.md CHANGED
@@ -33,14 +33,17 @@ cd ios && pod install
33
33
 
34
34
  ```sh
35
35
  import React, { useEffect } from 'react';
36
- import { Alert, View, Text } from 'react-native';
36
+ import { Alert, Button, View, Text } from 'react-native';
37
37
  import {
38
38
  OTAProvider,
39
39
  checkOTAUpdate,
40
40
  consumeOTAUpdateSuccessState,
41
+ reloadAppForOTAUpdate,
41
42
  } from 'react-native-3rddigital-appupdate';
42
43
 
43
44
  const App = () => {
45
+ const [pendingUpdate, setPendingUpdate] = React.useState(null);
46
+
44
47
  useEffect(() => {
45
48
  const initializeOTAUpdate = async () => {
46
49
  const updateState = await consumeOTAUpdateSuccessState();
@@ -57,6 +60,11 @@ const App = () => {
57
60
  key: 'YOUR_PROJECT_KEY',
58
61
  iosPackage: 'com.example.ios',
59
62
  androidPackage: 'com.example.android',
63
+ restartAfterInstall: false,
64
+ restartDelay: 1000,
65
+ onUpdateInstalled: (state) => {
66
+ setPendingUpdate(state);
67
+ },
60
68
  loaderOptions: {
61
69
  text: 'Downloading update...',
62
70
  showProgress: true,
@@ -75,6 +83,12 @@ const App = () => {
75
83
  <OTAProvider>
76
84
  <View>
77
85
  <Text>My App Content</Text>
86
+ {pendingUpdate ? (
87
+ <Button
88
+ title={`Reload to apply OTA v${pendingUpdate.version}`}
89
+ onPress={reloadAppForOTAUpdate}
90
+ />
91
+ ) : null}
78
92
  </View>
79
93
  </OTAProvider>
80
94
  );
@@ -99,6 +113,9 @@ Options:
99
113
  | `key` | string | ✅ | Project key to identify the app on your update server |
100
114
  | `iosPackage` | string | ✅ | iOS bundle/package identifier |
101
115
  | `androidPackage` | string | ✅ | Android bundle/package identifier |
116
+ | `restartAfterInstall` | boolean | ❌ | Whether the app should restart automatically after OTA install. Defaults to `true` |
117
+ | `restartDelay` | number | ❌ | Delay in milliseconds before restart after install. Defaults to `1000` |
118
+ | `onUpdateInstalled` | `(state: OTAUpdateSuccessState) => void` | ❌ | Called after the OTA bundle is installed, useful when `restartAfterInstall` is `false` and you want to trigger reload manually |
102
119
  | `loaderOptions` | object | ❌ | Customize loader UI (see below) |
103
120
  | `dialogOptions` | object | ❌ | Customize alert dialog UI (see below) |
104
121
 
@@ -121,6 +138,11 @@ Returns:
121
138
  | `appVersion` | string | Native app version associated with bundle |
122
139
  | `installedAt` | string | ISO timestamp when install completed |
123
140
 
141
+ 🔹 reloadAppForOTAUpdate()
142
+
143
+ - Manually reloads the app so an installed OTA bundle becomes active.
144
+ - Useful together with `restartAfterInstall: false` and `onUpdateInstalled`.
145
+
124
146
  🔹 Loader (AppLoader)
125
147
 
126
148
  - Global loader shown when downloading an update.
@@ -43,13 +43,19 @@ export const consumeOTAUpdateSuccessState = async () => {
43
43
  }
44
44
  return state;
45
45
  };
46
+ export const reloadAppForOTAUpdate = () => {
47
+ hotUpdate.resetApp();
48
+ };
46
49
  export const checkOTAUpdate = async ({
47
50
  key,
48
51
  iosPackage,
49
52
  androidPackage,
50
53
  loaderOptions,
51
54
  dialogOptions,
52
- baseUrl
55
+ baseUrl,
56
+ restartAfterInstall = true,
57
+ restartDelay = 1000,
58
+ onUpdateInstalled
53
59
  }) => {
54
60
  try {
55
61
  const API_URL = baseUrl;
@@ -75,12 +81,13 @@ export const checkOTAUpdate = async ({
75
81
  }
76
82
  },
77
83
  updateSuccess: () => {
78
- persistOTAUpdateSuccessState({
84
+ const updateState = {
79
85
  bundleId,
80
86
  version,
81
87
  appVersion: bundleAppVersion,
82
88
  installedAt: new Date().toISOString()
83
- }).finally(() => {
89
+ };
90
+ persistOTAUpdateSuccessState(updateState).finally(() => {
84
91
  axios.post(`${API_URL}bundles/${bundleId}/count`, {
85
92
  status: 'success'
86
93
  }, {
@@ -91,6 +98,7 @@ export const checkOTAUpdate = async ({
91
98
  }).catch(error => {
92
99
  console.warn('Failed to finalize OTA update success handling:', error);
93
100
  });
101
+ onUpdateInstalled?.(updateState);
94
102
  },
95
103
  updateFail: error => {
96
104
  axios.post(`${API_URL}bundles/${bundleId}/count`, {
@@ -108,8 +116,8 @@ export const checkOTAUpdate = async ({
108
116
  }
109
117
  }).finally(() => AppLoader.hide());
110
118
  },
111
- restartAfterInstall: true,
112
- restartDelay: 1000
119
+ restartAfterInstall,
120
+ restartDelay
113
121
  });
114
122
  };
115
123
  if (forceUpdate) {
@@ -1 +1 @@
1
- {"version":3,"names":["axios","Platform","ReactNativeBlobUtil","DeviceInfo","hotUpdate","AppAlertDialog","AppLoader","OTA_UPDATE_SUCCESS_FILE","fs","dirs","CacheDir","persistOTAUpdateSuccessState","state","writeFile","JSON","stringify","error","console","warn","readOTAUpdateSuccessState","exists","content","readFile","parse","consumeOTAUpdateSuccessState","unlink","checkOTAUpdate","key","iosPackage","androidPackage","loaderOptions","dialogOptions","baseUrl","API_URL","response","get","currentVersion","getCurrentVersion","data","OS","android","ios","version","forceUpdate","url","bundleId","currentAppVersion","getVersion","bundleAppVersion","appVersion","downloadAndReport","show","downloadBundleUri","progress","received","total","showProgress","percentage","Number","toFixed","updateProgress","updateSuccess","installedAt","Date","toISOString","finally","post","status","headers","hide","catch","updateFail","deviceInfo","model","getModel","brand","getBrand","systemName","getSystemName","systemVersion","getSystemVersion","restartAfterInstall","restartDelay","showMessage","title","message","confirmText","cancelText","onConfirm","onCancel","err"],"sourceRoot":"../../src","sources":["checkOTAUpdate.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["axios","Platform","ReactNativeBlobUtil","DeviceInfo","hotUpdate","AppAlertDialog","AppLoader","OTA_UPDATE_SUCCESS_FILE","fs","dirs","CacheDir","persistOTAUpdateSuccessState","state","writeFile","JSON","stringify","error","console","warn","readOTAUpdateSuccessState","exists","content","readFile","parse","consumeOTAUpdateSuccessState","unlink","reloadAppForOTAUpdate","resetApp","checkOTAUpdate","key","iosPackage","androidPackage","loaderOptions","dialogOptions","baseUrl","restartAfterInstall","restartDelay","onUpdateInstalled","API_URL","response","get","currentVersion","getCurrentVersion","data","OS","android","ios","version","forceUpdate","url","bundleId","currentAppVersion","getVersion","bundleAppVersion","appVersion","downloadAndReport","show","downloadBundleUri","progress","received","total","showProgress","percentage","Number","toFixed","updateProgress","updateSuccess","updateState","installedAt","Date","toISOString","finally","post","status","headers","hide","catch","updateFail","deviceInfo","model","getModel","brand","getBrand","systemName","getSystemName","systemVersion","getSystemVersion","showMessage","title","message","confirmText","cancelText","onConfirm","onCancel","err"],"sourceRoot":"../../src","sources":["checkOTAUpdate.ts"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
 
3
- export { checkOTAUpdate, consumeOTAUpdateSuccessState } from "./checkOTAUpdate.js";
3
+ export { checkOTAUpdate, consumeOTAUpdateSuccessState, reloadAppForOTAUpdate } from "./checkOTAUpdate.js";
4
4
  export { OTAProvider } from "./OTAProvider.js";
5
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["checkOTAUpdate","consumeOTAUpdateSuccessState","OTAProvider"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SACEA,cAAc,EACdC,4BAA4B,QAGvB,qBAAkB;AACzB,SAASC,WAAW,QAAQ,kBAAe","ignoreList":[]}
1
+ {"version":3,"names":["checkOTAUpdate","consumeOTAUpdateSuccessState","reloadAppForOTAUpdate","OTAProvider"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SACEA,cAAc,EACdC,4BAA4B,EAC5BC,qBAAqB,QAGhB,qBAAkB;AACzB,SAASC,WAAW,QAAQ,kBAAe","ignoreList":[]}
@@ -7,6 +7,9 @@ export type OTAUpdateProps = {
7
7
  loaderOptions?: LoaderOptions;
8
8
  dialogOptions?: Omit<DialogOptions, 'onConfirm' | 'onCancel'>;
9
9
  baseUrl: string;
10
+ restartAfterInstall?: boolean;
11
+ restartDelay?: number;
12
+ onUpdateInstalled?: (state: OTAUpdateSuccessState) => void;
10
13
  };
11
14
  export type OTAUpdateSuccessState = {
12
15
  bundleId: string;
@@ -15,5 +18,6 @@ export type OTAUpdateSuccessState = {
15
18
  installedAt: string;
16
19
  };
17
20
  export declare const consumeOTAUpdateSuccessState: () => Promise<OTAUpdateSuccessState | null>;
18
- export declare const checkOTAUpdate: ({ key, iosPackage, androidPackage, loaderOptions, dialogOptions, baseUrl, }: OTAUpdateProps) => Promise<void>;
21
+ export declare const reloadAppForOTAUpdate: () => void;
22
+ export declare const checkOTAUpdate: ({ key, iosPackage, androidPackage, loaderOptions, dialogOptions, baseUrl, restartAfterInstall, restartDelay, onUpdateInstalled, }: OTAUpdateProps) => Promise<void>;
19
23
  //# sourceMappingURL=checkOTAUpdate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkOTAUpdate.d.ts","sourceRoot":"","sources":["../../../src/checkOTAUpdate.ts"],"names":[],"mappings":"AAKA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5D,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,aAAa,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,UAAU,CAAC,CAAC;IAC9D,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAmCF,eAAO,MAAM,4BAA4B,6CAkBxC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,6EAOlC,cAAc,kBA+FhB,CAAC"}
1
+ {"version":3,"file":"checkOTAUpdate.d.ts","sourceRoot":"","sources":["../../../src/checkOTAUpdate.ts"],"names":[],"mappings":"AAKA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5D,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,aAAa,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,UAAU,CAAC,CAAC;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAmCF,eAAO,MAAM,4BAA4B,6CAkBxC,CAAC;AAEF,eAAO,MAAM,qBAAqB,YAEjC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,mIAUlC,cAAc,kBAmGhB,CAAC"}
@@ -1,3 +1,3 @@
1
- export { checkOTAUpdate, consumeOTAUpdateSuccessState, type OTAUpdateProps, type OTAUpdateSuccessState, } from './checkOTAUpdate';
1
+ export { checkOTAUpdate, consumeOTAUpdateSuccessState, reloadAppForOTAUpdate, type OTAUpdateProps, type OTAUpdateSuccessState, } from './checkOTAUpdate';
2
2
  export { OTAProvider } from './OTAProvider';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,KAAK,cAAc,EACnB,KAAK,qBAAqB,GAC3B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,qBAAqB,GAC3B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-3rddigital-appupdate",
3
- "version": "1.0.14",
3
+ "version": "1.0.17",
4
4
  "description": "A React Native library for seamless over-the-air (OTA) updates with version checks, automatic bundle download, and customizable user prompts for iOS and Android.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
package/scripts/bundle.js CHANGED
@@ -340,6 +340,15 @@ function isAppLikeTarget(targetName, productType) {
340
340
  ].some((suffix) => targetName.endsWith(suffix));
341
341
  }
342
342
 
343
+ function choosePreferredBuildConfig(buildConfigs, preferredNames = []) {
344
+ for (const preferredName of preferredNames) {
345
+ const match = buildConfigs.find((config) => config.name === preferredName);
346
+ if (match) return match;
347
+ }
348
+
349
+ return buildConfigs[0] ?? null;
350
+ }
351
+
343
352
  function getAndroidBuildGradlePath(projectRoot) {
344
353
  return findFirstExistingPath([
345
354
  path.join(projectRoot, 'android', 'app', 'build.gradle'),
@@ -534,34 +543,61 @@ function getIosTargetMetadata() {
534
543
  .map((configId) => configMap.get(configId))
535
544
  .filter(Boolean) ?? [];
536
545
 
537
- const preferredConfig =
538
- buildConfigs.find(
539
- (config) => config.name === configList?.defaultName
540
- ) ??
541
- buildConfigs.find((config) => config.name === 'Release') ??
542
- buildConfigs[0];
543
-
544
- if (!preferredConfig) return null;
545
-
546
- const buildConfigurationLabel = preferredConfig.name
547
- ? ` [${preferredConfig.name}]`
548
- : '';
549
-
550
- return {
551
- name: targetName,
552
- label: `${targetName}${buildConfigurationLabel}`,
553
- appId: preferredConfig.appId ?? null,
554
- version: preferredConfig.version ?? null,
555
- productName: preferredConfig.productName ?? targetName,
556
- buildConfiguration: preferredConfig.name ?? null,
557
- };
546
+ if (!buildConfigs.length) return null;
547
+
548
+ const configsByIdentity = new Map();
549
+
550
+ for (const buildConfig of buildConfigs) {
551
+ const identity = `${buildConfig.appId ?? 'no-app-id'}::${buildConfig.name ?? 'no-config-name'}`;
552
+ if (!configsByIdentity.has(identity)) {
553
+ configsByIdentity.set(identity, []);
554
+ }
555
+
556
+ configsByIdentity.get(identity).push(buildConfig);
557
+ }
558
+
559
+ const distinctConfigs = Array.from(configsByIdentity.values())
560
+ .map((configGroup) =>
561
+ choosePreferredBuildConfig(configGroup, [
562
+ configList?.defaultName,
563
+ 'Release',
564
+ 'Profile',
565
+ 'Debug',
566
+ ])
567
+ )
568
+ .filter(Boolean);
569
+
570
+ return distinctConfigs.map((selectedConfig) => {
571
+ const buildConfigurationLabel = selectedConfig.name
572
+ ? ` [${selectedConfig.name}]`
573
+ : '';
574
+
575
+ const appIdLabel = selectedConfig.appId
576
+ ? ` (${selectedConfig.appId})`
577
+ : '';
578
+
579
+ return {
580
+ name: `${targetName}::${selectedConfig.name ?? 'default'}::${selectedConfig.appId ?? 'no-app-id'}`,
581
+ targetName,
582
+ label: `${targetName}${buildConfigurationLabel}${appIdLabel}`,
583
+ appId: selectedConfig.appId ?? null,
584
+ version: selectedConfig.version ?? null,
585
+ productName: selectedConfig.productName ?? targetName,
586
+ buildConfiguration: selectedConfig.name ?? null,
587
+ };
588
+ });
558
589
  })
590
+ .flat()
559
591
  .filter(Boolean);
560
592
 
561
593
  const uniqueTargets = targets.filter(
562
594
  (target, index, allTargets) =>
563
- allTargets.findIndex((candidate) => candidate.name === target.name) ===
564
- index
595
+ allTargets.findIndex(
596
+ (candidate) =>
597
+ candidate.targetName === target.targetName &&
598
+ candidate.appId === target.appId &&
599
+ candidate.buildConfiguration === target.buildConfiguration
600
+ ) === index
565
601
  );
566
602
 
567
603
  return {
@@ -13,6 +13,9 @@ export type OTAUpdateProps = {
13
13
  loaderOptions?: LoaderOptions;
14
14
  dialogOptions?: Omit<DialogOptions, 'onConfirm' | 'onCancel'>;
15
15
  baseUrl: string;
16
+ restartAfterInstall?: boolean;
17
+ restartDelay?: number;
18
+ onUpdateInstalled?: (state: OTAUpdateSuccessState) => void;
16
19
  };
17
20
 
18
21
  export type OTAUpdateSuccessState = {
@@ -75,6 +78,10 @@ export const consumeOTAUpdateSuccessState = async () => {
75
78
  return state;
76
79
  };
77
80
 
81
+ export const reloadAppForOTAUpdate = () => {
82
+ hotUpdate.resetApp();
83
+ };
84
+
78
85
  export const checkOTAUpdate = async ({
79
86
  key,
80
87
  iosPackage,
@@ -82,6 +89,9 @@ export const checkOTAUpdate = async ({
82
89
  loaderOptions,
83
90
  dialogOptions,
84
91
  baseUrl,
92
+ restartAfterInstall = true,
93
+ restartDelay = 1000,
94
+ onUpdateInstalled,
85
95
  }: OTAUpdateProps) => {
86
96
  try {
87
97
  const API_URL = baseUrl;
@@ -116,12 +126,14 @@ export const checkOTAUpdate = async ({
116
126
  }
117
127
  },
118
128
  updateSuccess: () => {
119
- persistOTAUpdateSuccessState({
129
+ const updateState = {
120
130
  bundleId,
121
131
  version,
122
132
  appVersion: bundleAppVersion,
123
133
  installedAt: new Date().toISOString(),
124
- })
134
+ };
135
+
136
+ persistOTAUpdateSuccessState(updateState)
125
137
  .finally(() => {
126
138
  axios
127
139
  .post(
@@ -137,6 +149,8 @@ export const checkOTAUpdate = async ({
137
149
  error
138
150
  );
139
151
  });
152
+
153
+ onUpdateInstalled?.(updateState);
140
154
  },
141
155
  updateFail: (error) => {
142
156
  axios
@@ -156,8 +170,8 @@ export const checkOTAUpdate = async ({
156
170
  )
157
171
  .finally(() => AppLoader.hide());
158
172
  },
159
- restartAfterInstall: true,
160
- restartDelay: 1000,
173
+ restartAfterInstall,
174
+ restartDelay,
161
175
  });
162
176
  };
163
177
 
package/src/index.tsx CHANGED
@@ -1,6 +1,7 @@
1
1
  export {
2
2
  checkOTAUpdate,
3
3
  consumeOTAUpdateSuccessState,
4
+ reloadAppForOTAUpdate,
4
5
  type OTAUpdateProps,
5
6
  type OTAUpdateSuccessState,
6
7
  } from './checkOTAUpdate';