@novacraft-engineering/pulsar-code-push 1.6.0 → 1.6.2
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/CodePush.js
CHANGED
|
@@ -9,6 +9,12 @@ import { setTargetingInfo, getTargetingInfo } from "./targeting";
|
|
|
9
9
|
let NativeCodePush = require("react-native").NativeModules.CodePush;
|
|
10
10
|
const PackageMixins = require("./package-mixins")(NativeCodePush);
|
|
11
11
|
|
|
12
|
+
// Apps that choose their deployment key in JS (per environment) leave the native one empty, so the
|
|
13
|
+
// launch-time status report has no key. Fall back to the first key the app checks with (its primary
|
|
14
|
+
// backend) and send a report that was held for want of one as soon as that key is known.
|
|
15
|
+
let fallbackDeployment = null;
|
|
16
|
+
let reportAwaitingKey = null;
|
|
17
|
+
|
|
12
18
|
async function checkForUpdate(deploymentKey = null, handleBinaryVersionMismatchCallback = null, serverUrl = null) {
|
|
13
19
|
/*
|
|
14
20
|
* Before we ask the server if an update exists, we
|
|
@@ -39,6 +45,14 @@ async function checkForUpdate(deploymentKey = null, handleBinaryVersionMismatchC
|
|
|
39
45
|
...(deploymentKey ? { deploymentKey } : {}),
|
|
40
46
|
...(serverUrl ? { serverUrl } : {}),
|
|
41
47
|
};
|
|
48
|
+
if (config.deploymentKey && !fallbackDeployment) {
|
|
49
|
+
fallbackDeployment = { deploymentKey: config.deploymentKey, serverUrl: config.serverUrl };
|
|
50
|
+
if (reportAwaitingKey) {
|
|
51
|
+
const heldReport = reportAwaitingKey;
|
|
52
|
+
reportAwaitingKey = null;
|
|
53
|
+
tryReportStatus(heldReport);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
42
56
|
const sdk = getPromisifiedSdk(requestFetchAdapter, config);
|
|
43
57
|
|
|
44
58
|
// Use dynamically overridden getCurrentPackage() during tests.
|
|
@@ -192,8 +206,18 @@ async function notifyApplicationReadyInternal() {
|
|
|
192
206
|
return statusReport;
|
|
193
207
|
}
|
|
194
208
|
|
|
209
|
+
// Report an install to the Pulsar server that delivered it. Its download links are
|
|
210
|
+
// `<server>/download/...`, so the package names its own server — which matters when the native
|
|
211
|
+
// config points elsewhere (an Android strings.xml that spells the key `CodePushServerURL`, the iOS
|
|
212
|
+
// spelling, is ignored and falls back to the SDK's default).
|
|
213
|
+
function pulsarServerFor(localPackage) {
|
|
214
|
+
const match = /^(https?:\/\/[^/?#]+)\/download\//.exec(localPackage?.downloadUrl || '');
|
|
215
|
+
return match ? match[1] : null;
|
|
216
|
+
}
|
|
217
|
+
|
|
195
218
|
async function tryReportStatus(statusReport, retryOnAppResume) {
|
|
196
|
-
const
|
|
219
|
+
const nativeConfig = await getConfiguration();
|
|
220
|
+
const config = nativeConfig.deploymentKey || !fallbackDeployment ? nativeConfig : { ...nativeConfig, ...fallbackDeployment };
|
|
197
221
|
const previousLabelOrAppVersion = statusReport.previousLabelOrAppVersion;
|
|
198
222
|
const previousDeploymentKey = statusReport.previousDeploymentKey || config.deploymentKey;
|
|
199
223
|
try {
|
|
@@ -201,6 +225,7 @@ async function tryReportStatus(statusReport, retryOnAppResume) {
|
|
|
201
225
|
log(`Reporting binary update (${statusReport.appVersion})`);
|
|
202
226
|
|
|
203
227
|
if (!config.deploymentKey) {
|
|
228
|
+
reportAwaitingKey = statusReport;
|
|
204
229
|
throw new Error("Deployment key is missed");
|
|
205
230
|
}
|
|
206
231
|
|
|
@@ -215,8 +240,9 @@ async function tryReportStatus(statusReport, retryOnAppResume) {
|
|
|
215
240
|
await NativeCodePush.setLatestRollbackInfo(statusReport.package.packageHash);
|
|
216
241
|
}
|
|
217
242
|
|
|
218
|
-
|
|
219
|
-
const
|
|
243
|
+
const deliveredBy = pulsarServerFor(statusReport.package);
|
|
244
|
+
const reportConfig = {...config, deploymentKey: statusReport.package.deploymentKey, ...(deliveredBy ? {serverUrl: deliveredBy} : {})};
|
|
245
|
+
const sdk = getPromisifiedSdk(requestFetchAdapter, reportConfig);
|
|
220
246
|
await sdk.reportStatusDeploy(statusReport.package, statusReport.status, previousLabelOrAppVersion, previousDeploymentKey);
|
|
221
247
|
}
|
|
222
248
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @novacraft-engineering/pulsar-code-push
|
|
2
2
|
|
|
3
|
-
The React Native client for [Pulsar](https://
|
|
3
|
+
The React Native client for [Pulsar](https://usepulsar.dev) — **over-the-air JavaScript updates** for your app, no app-store review. A free, self-hostable **CodePush alternative** for React Native.
|
|
4
4
|
|
|
5
5
|
This is a full CodePush client (native iOS + Android modules), not a wrapper. It is a fork of
|
|
6
6
|
[`@revopush/react-native-code-push`](https://github.com/revopush/react-native-code-push) — itself the
|
|
@@ -8,6 +8,13 @@ New-Architecture-maintained continuation of Microsoft's original
|
|
|
8
8
|
[`react-native-code-push`](https://github.com/microsoft/react-native-code-push) (archived March 2025).
|
|
9
9
|
It speaks the CodePush protocol, so it works against any CodePush-compatible server; it defaults to Pulsar.
|
|
10
10
|
|
|
11
|
+
## Why
|
|
12
|
+
|
|
13
|
+
Microsoft App Center CodePush shut down in March 2025 and Expo's EAS Update only covers Expo-managed
|
|
14
|
+
projects. Pulsar keeps the CodePush protocol every bare React Native app already knows, adds staged
|
|
15
|
+
rollouts, instant rollback, differential updates and per-release health metrics, and can be self-hosted.
|
|
16
|
+
Read the full comparison at [usepulsar.dev/codepush-alternative](https://usepulsar.dev/codepush-alternative).
|
|
17
|
+
|
|
11
18
|
## Install
|
|
12
19
|
|
|
13
20
|
```bash
|
|
@@ -25,7 +32,7 @@ Autolinking registers the native module on both platforms (RN 0.70+, New Archite
|
|
|
25
32
|
<key>CodePushDeploymentKey</key>
|
|
26
33
|
<string>YOUR_DEPLOYMENT_KEY</string>
|
|
27
34
|
<key>CodePushServerURL</key>
|
|
28
|
-
<string>https://api.
|
|
35
|
+
<string>https://api.usepulsar.dev</string>
|
|
29
36
|
```
|
|
30
37
|
|
|
31
38
|
**Android** — `android/app/src/main/res/values/strings.xml`:
|
|
@@ -33,7 +40,7 @@ Autolinking registers the native module on both platforms (RN 0.70+, New Archite
|
|
|
33
40
|
```xml
|
|
34
41
|
<resources>
|
|
35
42
|
<string moduleConfig="true" name="CodePushDeploymentKey">YOUR_DEPLOYMENT_KEY</string>
|
|
36
|
-
<string moduleConfig="true" name="CodePushServerURL">https://api.
|
|
43
|
+
<string moduleConfig="true" name="CodePushServerURL">https://api.usepulsar.dev</string>
|
|
37
44
|
</resources>
|
|
38
45
|
```
|
|
39
46
|
|
|
@@ -56,14 +63,31 @@ The full CodePush API is available — `codePush.sync()`, `codePush.checkForUpda
|
|
|
56
63
|
`InstallMode`, `CheckFrequency`, `notifyAppReady()`, rollout %, mandatory updates, binary-version
|
|
57
64
|
targeting, differential updates, automatic rollback, and download/install telemetry (reported to Pulsar).
|
|
58
65
|
|
|
66
|
+
## Migrating from CodePush or RevoPush
|
|
67
|
+
|
|
68
|
+
Swap the import and point `CodePushServerURL` at Pulsar — the native modules, the JS API and the
|
|
69
|
+
package-hash algorithm are unchanged, so devices already running your current bundle correctly
|
|
70
|
+
report "up to date" instead of re-downloading it.
|
|
71
|
+
|
|
72
|
+
```diff
|
|
73
|
+
-import codePush from 'react-native-code-push';
|
|
74
|
+
+import codePush from '@novacraft-engineering/pulsar-code-push';
|
|
75
|
+
```
|
|
76
|
+
|
|
59
77
|
## Releasing
|
|
60
78
|
|
|
61
79
|
Use the Pulsar CLI ([`@novacraft-engineering/pulsar-cli`](https://github.com/Novacraft-Africa/pulsar-cli)):
|
|
62
80
|
|
|
63
81
|
```bash
|
|
64
|
-
npx pulsar release MyApp Staging --platform ios --target 1.0.0
|
|
82
|
+
npx @novacraft-engineering/pulsar-cli release MyApp Staging --platform ios --target 1.0.0
|
|
65
83
|
```
|
|
66
84
|
|
|
85
|
+
## Related
|
|
86
|
+
|
|
87
|
+
- [Pulsar vs CodePush vs RevoPush](https://usepulsar.dev/blog/codepush-vs-revopush-vs-pulsar)
|
|
88
|
+
- [Microsoft CodePush shutdown: what to move to](https://usepulsar.dev/blog/microsoft-codepush-shutdown-alternatives)
|
|
89
|
+
- [How React Native OTA updates actually work](https://usepulsar.dev/blog/how-react-native-ota-updates-work)
|
|
90
|
+
|
|
67
91
|
## License
|
|
68
92
|
|
|
69
93
|
MIT. Original CodePush © Microsoft; RevoPush fork © Revopush; this Pulsar distribution © Novacraft Engineering.
|
|
@@ -93,6 +93,7 @@ public class CodePush implements ReactPackage {
|
|
|
93
93
|
if (publicKeyFromStrings != null) mPublicKey = publicKeyFromStrings;
|
|
94
94
|
|
|
95
95
|
String serverUrlFromStrings = getCustomPropertyFromStringsIfExist("ServerUrl");
|
|
96
|
+
if (serverUrlFromStrings == null) serverUrlFromStrings = getCustomPropertyFromStringsIfExist("ServerURL");
|
|
96
97
|
if (serverUrlFromStrings != null) mServerUrl = serverUrlFromStrings;
|
|
97
98
|
|
|
98
99
|
// ignore liveReload when CodePush is initializing so that unneccessary cache could be cleared
|
|
@@ -34,7 +34,7 @@ static NSString * const PublicKeyKey = @"publicKey";
|
|
|
34
34
|
NSString *appVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
|
|
35
35
|
NSString *buildVersion = [infoDictionary objectForKey:(NSString *)kCFBundleVersionKey];
|
|
36
36
|
NSString *deploymentKey = [infoDictionary objectForKey:@"CodePushDeploymentKey"];
|
|
37
|
-
NSString *serverURL = [infoDictionary objectForKey:@"CodePushServerURL"];
|
|
37
|
+
NSString *serverURL = [infoDictionary objectForKey:@"CodePushServerURL"] ?: [infoDictionary objectForKey:@"CodePushServerUrl"];
|
|
38
38
|
NSString *publicKey = [infoDictionary objectForKey:@"CodePushPublicKey"];
|
|
39
39
|
|
|
40
40
|
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
|
package/package.json
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@novacraft-engineering/pulsar-code-push",
|
|
3
|
-
"version": "1.6.
|
|
4
|
-
"description": "Pulsar OTA client for React Native
|
|
3
|
+
"version": "1.6.2",
|
|
4
|
+
"description": "Pulsar OTA client for React Native — over-the-air JavaScript updates. A CodePush-compatible client (RevoPush lineage) pointed at Pulsar.",
|
|
5
5
|
"main": "CodePush.js",
|
|
6
6
|
"typings": "typings/react-native-code-push.d.ts",
|
|
7
|
-
"homepage": "https://
|
|
7
|
+
"homepage": "https://usepulsar.dev",
|
|
8
8
|
"keywords": [
|
|
9
|
-
"react-native",
|
|
10
9
|
"code-push",
|
|
11
10
|
"codepush",
|
|
12
|
-
"
|
|
11
|
+
"codepush-alternative",
|
|
12
|
+
"hot-update",
|
|
13
13
|
"ota",
|
|
14
|
+
"ota-updates",
|
|
14
15
|
"over-the-air",
|
|
15
|
-
"
|
|
16
|
+
"pulsar",
|
|
17
|
+
"react-native",
|
|
18
|
+
"react-native-ota"
|
|
16
19
|
],
|
|
17
20
|
"author": "Novacraft Engineering",
|
|
18
21
|
"license": "MIT",
|