pulse-updates 1.0.16 → 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/package.json +1 -1
- package/scripts/publish.mjs +91 -33
package/package.json
CHANGED
package/scripts/publish.mjs
CHANGED
|
@@ -157,12 +157,15 @@ function getMimeType(ext) {
|
|
|
157
157
|
*/
|
|
158
158
|
function findHermesc(platform) {
|
|
159
159
|
const possiblePaths = [
|
|
160
|
-
// iOS paths
|
|
160
|
+
// iOS paths (present once Pods are installed)
|
|
161
161
|
'ios/Pods/hermes-engine/destroot/bin/hermesc',
|
|
162
|
+
// hermesc as shipped inside react-native itself (host-arch dirs vary by RN version)
|
|
162
163
|
'node_modules/react-native/sdks/hermesc/osx-bin/hermesc',
|
|
163
164
|
'node_modules/react-native/sdks/hermesc/linux64-bin/hermesc',
|
|
164
|
-
|
|
165
|
+
'node_modules/react-native/sdks/hermesc/win64-bin/hermesc.exe',
|
|
166
|
+
// Android paths (present once an Android build has run)
|
|
165
167
|
'node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/hermesc',
|
|
168
|
+
'node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/tools/hermesc/hermesc',
|
|
166
169
|
];
|
|
167
170
|
|
|
168
171
|
for (const p of possiblePaths) {
|
|
@@ -172,12 +175,59 @@ function findHermesc(platform) {
|
|
|
172
175
|
}
|
|
173
176
|
}
|
|
174
177
|
|
|
175
|
-
// Try to find via
|
|
178
|
+
// Try to find via PATH
|
|
176
179
|
try {
|
|
177
|
-
|
|
180
|
+
const viaPath = execSync('command -v hermesc', { encoding: 'utf8' }).trim();
|
|
181
|
+
if (viaPath) return viaPath;
|
|
178
182
|
} catch {
|
|
179
|
-
|
|
183
|
+
/* not on PATH */
|
|
180
184
|
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Locate hermesc, and if it isn't there yet, try to materialize it.
|
|
190
|
+
* A React Native app may only carry hermesc inside the installed CocoaPods (it
|
|
191
|
+
* does not always ship in node_modules for every RN version), so on macOS a
|
|
192
|
+
* missing compiler often means "Pods aren't installed" — which we fix by running
|
|
193
|
+
* pod-install once, then re-checking. Anything else is a hard stop: we NEVER
|
|
194
|
+
* silently fall back to a plain-JS OTA bundle (that would ship readable source
|
|
195
|
+
* over the air). Hermes is mandatory on every publish.
|
|
196
|
+
*/
|
|
197
|
+
function ensureHermesc(platform) {
|
|
198
|
+
let hermesc = findHermesc(platform);
|
|
199
|
+
if (hermesc) return hermesc;
|
|
200
|
+
|
|
201
|
+
const onMac = process.platform === 'darwin';
|
|
202
|
+
const hasPodfile = fs.existsSync(path.resolve('ios/Podfile'));
|
|
203
|
+
if (onMac && hasPodfile) {
|
|
204
|
+
logWarning('Hermes compiler not found — installing iOS Pods to obtain it (one-shot)...');
|
|
205
|
+
try {
|
|
206
|
+
// Prefer a repo pod-install helper if the app provides one, else npx pod-install.
|
|
207
|
+
const repoHelper = path.resolve('scripts/pod-install-if-mac.js');
|
|
208
|
+
const cmd = fs.existsSync(repoHelper)
|
|
209
|
+
? `node ${repoHelper}`
|
|
210
|
+
: 'npx pod-install ios';
|
|
211
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
212
|
+
} catch (error) {
|
|
213
|
+
throw new Error(
|
|
214
|
+
`Hermes compiler not found and automatic pod install failed (${error.message}). ` +
|
|
215
|
+
'Run `npx pod-install ios` (or `cd ios && pod install`) and publish again.'
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
hermesc = findHermesc(platform);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (!hermesc) {
|
|
222
|
+
throw new Error(
|
|
223
|
+
'Hermes compiler (hermesc) could not be located. Pulse publishes Hermes bytecode only — ' +
|
|
224
|
+
'a plain-JS OTA bundle must never be shipped. Install it before publishing:\n' +
|
|
225
|
+
' • macOS: `npx pod-install ios` (materializes ios/Pods/hermes-engine/.../hermesc)\n' +
|
|
226
|
+
' • or ensure react-native ships hermesc under node_modules/react-native/sdks/hermesc/\n' +
|
|
227
|
+
' • or put hermesc on PATH.'
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
return hermesc;
|
|
181
231
|
}
|
|
182
232
|
|
|
183
233
|
/**
|
|
@@ -213,43 +263,51 @@ function createBundle(platform, bundleDir, entryFile = 'index.ts') {
|
|
|
213
263
|
* Compile bundle with Hermes
|
|
214
264
|
*/
|
|
215
265
|
function compileWithHermes(bundlePath, platform) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
return bundlePath;
|
|
220
|
-
}
|
|
266
|
+
// Mandatory: locate (and if needed materialize) hermesc. Throws rather than
|
|
267
|
+
// degrading to a plain-JS bundle — see ensureHermesc.
|
|
268
|
+
const hermesc = ensureHermesc(platform);
|
|
221
269
|
|
|
222
270
|
const hbcPath = bundlePath.replace('.bundle', '.hbc');
|
|
223
271
|
|
|
224
272
|
log(` Compiling with Hermes...`, colors.dim);
|
|
225
273
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
274
|
+
// -emit-binary: Hermes bytecode.
|
|
275
|
+
// -fstrip-function-names: drop JS function names from the string table (smaller
|
|
276
|
+
// bundle, and function names are the biggest readability gift to anyone
|
|
277
|
+
// inspecting the bytecode). Trade-off: JS function names disappear from crash
|
|
278
|
+
// stack traces. Does NOT touch string literals.
|
|
279
|
+
const hermesArgs = ['-emit-binary', '-fstrip-function-names', '-out', hbcPath, bundlePath];
|
|
280
|
+
|
|
281
|
+
// Use spawnSync with larger buffer to avoid ENOBUFS error
|
|
282
|
+
const result = spawnSync(hermesc, hermesArgs, {
|
|
283
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
284
|
+
maxBuffer: 100 * 1024 * 1024, // 100MB buffer
|
|
285
|
+
encoding: 'utf8',
|
|
286
|
+
});
|
|
233
287
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
288
|
+
if (result.error) {
|
|
289
|
+
throw result.error;
|
|
290
|
+
}
|
|
237
291
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
292
|
+
if (result.status !== 0) {
|
|
293
|
+
const stderr = result.stderr || '';
|
|
294
|
+
throw new Error(`Hermes exited with code ${result.status}: ${stderr.slice(0, 500)}`);
|
|
295
|
+
}
|
|
242
296
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
297
|
+
// Remove the plain JS bundle, keep only HBC
|
|
298
|
+
fs.unlinkSync(bundlePath);
|
|
299
|
+
// Rename .hbc to .bundle for compatibility
|
|
300
|
+
const finalPath = bundlePath;
|
|
301
|
+
fs.renameSync(hbcPath, finalPath);
|
|
302
|
+
|
|
303
|
+
// Belt-and-suspenders: the launch asset MUST be Hermes bytecode. If for any
|
|
304
|
+
// reason it isn't, fail the publish instead of shipping readable JS OTA.
|
|
305
|
+
if (!isHermesBytecode(finalPath)) {
|
|
306
|
+
throw new Error(
|
|
307
|
+
'Post-compile check failed: launch bundle is not Hermes bytecode. Refusing to publish a plain-JS OTA bundle.'
|
|
308
|
+
);
|
|
252
309
|
}
|
|
310
|
+
return finalPath;
|
|
253
311
|
}
|
|
254
312
|
|
|
255
313
|
/**
|