pulse-updates 1.0.17 → 1.0.18
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 +50 -19
package/package.json
CHANGED
package/scripts/publish.mjs
CHANGED
|
@@ -187,12 +187,14 @@ function findHermesc(platform) {
|
|
|
187
187
|
|
|
188
188
|
/**
|
|
189
189
|
* Locate hermesc, and if it isn't there yet, try to materialize it.
|
|
190
|
+
* Only used when the caller has REQUIRED Hermes (config.requireHermes / --require-hermes).
|
|
190
191
|
* A React Native app may only carry hermesc inside the installed CocoaPods (it
|
|
191
192
|
* does not always ship in node_modules for every RN version), so on macOS a
|
|
192
193
|
* missing compiler often means "Pods aren't installed" — which we fix by running
|
|
193
|
-
* pod-install once, then re-checking.
|
|
194
|
-
* silently
|
|
195
|
-
*
|
|
194
|
+
* pod-install once, then re-checking. If it still can't be found we throw, rather
|
|
195
|
+
* than silently shipping a plain-JS OTA bundle (readable source over the air).
|
|
196
|
+
* Apps that intentionally run without Hermes must NOT set requireHermes — they get
|
|
197
|
+
* the default best-effort path (compile if hermesc is present, plain JS otherwise).
|
|
196
198
|
*/
|
|
197
199
|
function ensureHermesc(platform) {
|
|
198
200
|
let hermesc = findHermesc(platform);
|
|
@@ -260,23 +262,42 @@ function createBundle(platform, bundleDir, entryFile = 'index.ts') {
|
|
|
260
262
|
}
|
|
261
263
|
|
|
262
264
|
/**
|
|
263
|
-
* Compile bundle with Hermes
|
|
265
|
+
* Compile bundle with Hermes.
|
|
266
|
+
*
|
|
267
|
+
* Default (best-effort): if hermesc is found, compile to bytecode; if not, warn and
|
|
268
|
+
* ship the plain JS bundle — this is correct for apps that don't run Hermes (JSC,
|
|
269
|
+
* or an intentionally plain-JS runtime), which is why it stays the default.
|
|
270
|
+
*
|
|
271
|
+
* With options.requireHermes (config.requireHermes / --require-hermes): the app has
|
|
272
|
+
* declared it runs on Hermes, so a plain-JS OTA would be both readable source and a
|
|
273
|
+
* runtime mismatch. In that mode we locate-or-materialize hermesc (throwing if we
|
|
274
|
+
* can't), pass -fstrip-function-names to shrink the string table, and assert the
|
|
275
|
+
* output is bytecode before returning. eSound and Lyra run in this mode.
|
|
264
276
|
*/
|
|
265
|
-
function compileWithHermes(bundlePath, platform) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
277
|
+
function compileWithHermes(bundlePath, platform, options = {}) {
|
|
278
|
+
const requireHermes = !!options.requireHermes;
|
|
279
|
+
|
|
280
|
+
// In required mode, ensureHermesc throws if it can't obtain a compiler.
|
|
281
|
+
// Otherwise fall back to best-effort discovery.
|
|
282
|
+
const hermesc = requireHermes ? ensureHermesc(platform) : findHermesc(platform);
|
|
283
|
+
if (!hermesc) {
|
|
284
|
+
// Only reachable when Hermes is NOT required.
|
|
285
|
+
logWarning('Hermes compiler not found, using plain JS bundle');
|
|
286
|
+
return bundlePath;
|
|
287
|
+
}
|
|
269
288
|
|
|
270
289
|
const hbcPath = bundlePath.replace('.bundle', '.hbc');
|
|
271
290
|
|
|
272
291
|
log(` Compiling with Hermes...`, colors.dim);
|
|
273
292
|
|
|
274
293
|
// -emit-binary: Hermes bytecode.
|
|
275
|
-
// -fstrip-function-names: drop JS function names from the
|
|
276
|
-
//
|
|
277
|
-
//
|
|
278
|
-
//
|
|
279
|
-
const hermesArgs = ['-emit-binary'
|
|
294
|
+
// -fstrip-function-names (required mode only): drop JS function names from the
|
|
295
|
+
// bytecode string table (smaller bundle, less readable). Trade-off: JS function
|
|
296
|
+
// names disappear from crash stack traces, so it stays opt-in via requireHermes.
|
|
297
|
+
// Does NOT touch string literals.
|
|
298
|
+
const hermesArgs = ['-emit-binary'];
|
|
299
|
+
if (requireHermes) hermesArgs.push('-fstrip-function-names');
|
|
300
|
+
hermesArgs.push('-out', hbcPath, bundlePath);
|
|
280
301
|
|
|
281
302
|
// Use spawnSync with larger buffer to avoid ENOBUFS error
|
|
282
303
|
const result = spawnSync(hermesc, hermesArgs, {
|
|
@@ -286,12 +307,17 @@ function compileWithHermes(bundlePath, platform) {
|
|
|
286
307
|
});
|
|
287
308
|
|
|
288
309
|
if (result.error) {
|
|
289
|
-
throw result.error;
|
|
310
|
+
if (requireHermes) throw result.error;
|
|
311
|
+
logWarning(`Hermes compilation failed: ${result.error.message}`);
|
|
312
|
+
return bundlePath;
|
|
290
313
|
}
|
|
291
314
|
|
|
292
315
|
if (result.status !== 0) {
|
|
293
316
|
const stderr = result.stderr || '';
|
|
294
|
-
|
|
317
|
+
const message = `Hermes exited with code ${result.status}: ${stderr.slice(0, 500)}`;
|
|
318
|
+
if (requireHermes) throw new Error(message);
|
|
319
|
+
logWarning(`Hermes compilation failed: ${message}`);
|
|
320
|
+
return bundlePath;
|
|
295
321
|
}
|
|
296
322
|
|
|
297
323
|
// Remove the plain JS bundle, keep only HBC
|
|
@@ -300,9 +326,8 @@ function compileWithHermes(bundlePath, platform) {
|
|
|
300
326
|
const finalPath = bundlePath;
|
|
301
327
|
fs.renameSync(hbcPath, finalPath);
|
|
302
328
|
|
|
303
|
-
//
|
|
304
|
-
|
|
305
|
-
if (!isHermesBytecode(finalPath)) {
|
|
329
|
+
// In required mode, belt-and-suspenders: the launch asset MUST be Hermes bytecode.
|
|
330
|
+
if (requireHermes && !isHermesBytecode(finalPath)) {
|
|
306
331
|
throw new Error(
|
|
307
332
|
'Post-compile check failed: launch bundle is not Hermes bytecode. Refusing to publish a plain-JS OTA bundle.'
|
|
308
333
|
);
|
|
@@ -714,6 +739,12 @@ function loadConfig(options) {
|
|
|
714
739
|
skipBundle: options['skip-bundle'] || false,
|
|
715
740
|
build: options.build || process.env.PULSE_BUILD || fileConfig.build || null,
|
|
716
741
|
message: options.message || fileConfig.message || null,
|
|
742
|
+
// Opt-in: the app runs on Hermes, so a plain-JS OTA must never be shipped.
|
|
743
|
+
// Makes a missing/failing hermesc fatal (with a one-shot pod-install attempt on
|
|
744
|
+
// macOS), enables -fstrip-function-names, and asserts bytecode output.
|
|
745
|
+
// Leave unset for apps that intentionally run plain JS (best-effort default).
|
|
746
|
+
requireHermes: options['require-hermes'] || process.env.PULSE_REQUIRE_HERMES === '1' ||
|
|
747
|
+
fileConfig.requireHermes || false,
|
|
717
748
|
};
|
|
718
749
|
}
|
|
719
750
|
|
|
@@ -763,7 +794,7 @@ async function publish(options) {
|
|
|
763
794
|
|
|
764
795
|
// Step 2: Compile with Hermes
|
|
765
796
|
logStep('2/6', 'Compiling with Hermes...');
|
|
766
|
-
compileWithHermes(bundlePath, config.platform);
|
|
797
|
+
compileWithHermes(bundlePath, config.platform, { requireHermes: config.requireHermes });
|
|
767
798
|
logSuccess('Hermes compilation complete');
|
|
768
799
|
} else {
|
|
769
800
|
logStep('1/6', 'Skipping bundle creation (--skip-bundle)');
|