Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions harmony/pushy/src/main/ets/PushyFileJSBundleProvider.ets
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,35 @@ import { UpdateContext } from './UpdateContext';

export class PushyFileJSBundleProvider extends JSBundleProvider {
private updateContext: UpdateContext;
private path: string = '';

constructor(context: common.UIAbilityContext) {
super();
this.updateContext = new UpdateContext(context);
this.path = this.updateContext.getBundleUrl();
}

getURL(): string {
return this.path;
return this.updateContext.getBundleUrl();
}

async getBundle(): Promise<FileJSBundle> {
if (!this.path) {
const path = this.updateContext.getBundleUrl();
if (!path) {
throw new JSBundleProviderError({
whatHappened: 'No pushy bundle found. using default bundle',
howCanItBeFixed: [''],
});
}
try {
await fs.access(this.path, fs.OpenMode.READ_ONLY);
await fs.access(path, fs.OpenMode.READ_ONLY);
return {
filePath: this.path,
filePath: path,
};
} catch (error) {
throw new JSBundleProviderError({
whatHappened: `Couldn't load JSBundle from ${this.path}`,
whatHappened: `Couldn't load JSBundle from ${path}`,
extraData: error,
howCanItBeFixed: [
`Check if a bundle exists at "${this.path}" on your device.`,
`Check if a bundle exists at "${path}" on your device.`,
],
});
}
Expand Down
15 changes: 13 additions & 2 deletions harmony/pushy/src/main/ets/PushyTurboModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ export class PushyTurboModule extends UITurboModule {
await this.mUiCtx.startAbility(want);
}

private async reloadBridge(): Promise<void> {
const devToolsController = (this.ctx as Record<string, any>).devToolsController;
if (devToolsController) {
logger.debug(TAG, 'reloadBridge via devToolsController RELOAD');
devToolsController.eventEmitter.emit("RELOAD", { reason: 'HotReload2' });
} else {
logger.debug(TAG, 'reloadBridge via restartAbility');
await this.restartAbility();
Comment on lines +68 to +75

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== devTools reload hook usages =='
rg -n -C2 --glob '*.ts' --glob '*.ets' '\bdevToolsController\b|\beventEmitter\b|\bRELOAD\b|\bHotReload2\b' .

echo
echo '== UITurboModuleContext / related declarations =='
rg -n -C2 --glob '*.d.ts' --glob '*.ts' --glob '*.ets' '\b(interface|type|class)\s+UITurboModuleContext\b' .

Repository: reactnativecn/react-native-update

Length of output: 1060


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== PushyTurboModule relevant section =='
sed -n '1,220p' harmony/pushy/src/main/ets/PushyTurboModule.ts | cat -n

echo
echo '== Search for reloadBridge callers and restartAbility =='
rg -n -C3 'reloadBridge\(|restartAbility\(|reloadUpdate\(|restartApp\(' harmony/pushy/src/main/ets/PushyTurboModule.ts harmony/pushy/src/main/ets

echo
echo '== Search for devToolsController contract definitions/usages =='
rg -n -C3 --glob '*.ts' --glob '*.ets' --glob '*.d.ts' 'devToolsController|eventEmitter|RELOAD|HotReload2|UITurboModuleContext|TurboModuleContext' harmony .

Repository: reactnativecn/react-native-update

Length of output: 24960


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== all devToolsController references =='
rg -n -C3 --glob '*.ts' --glob '*.ets' --glob '*.d.ts' 'devToolsController' .

echo
echo '== all TurboModule context type references =='
rg -n -C3 --glob '*.ts' --glob '*.ets' --glob '*.d.ts' 'TurboModuleContext|UITurboModuleContext|ctx:' harmony

echo
echo '== PushyTurboModule file excerpt =='
sed -n '1,180p' harmony/pushy/src/main/ets/PushyTurboModule.ts | cat -n

Repository: reactnativecn/react-native-update

Length of output: 10099


Guard the RELOAD path with the restart fallback. If eventEmitter is missing or emit('RELOAD', ...) throws, reloadUpdate() and restartApp() reject instead of falling back to restartAbility().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harmony/pushy/src/main/ets/PushyTurboModule.ts` around lines 68 - 75, The
reloadBridge path currently assumes
devToolsController.eventEmitter.emit("RELOAD", ...) will always succeed, so
reloadUpdate() and restartApp() can fail instead of using the restartAbility
fallback. Update reloadBridge() to guard the RELOAD branch in PushyTurboModule
by checking that eventEmitter exists and wrapping the emit call in error
handling; if emit is unavailable or throws, fall back to restartAbility() just
like the else path. Keep the logic localized to reloadBridge() so callers like
reloadUpdate() and restartApp() continue to resolve through the fallback.

}
}

getConstants(): Object {
logger.debug(TAG, ',call getConstants');
const packageVersion = this.context.getPackageVersion();
Expand Down Expand Up @@ -121,7 +132,7 @@ export class PushyTurboModule extends UITurboModule {

try {
this.context.switchVersion(hash);
await this.restartAbility();
await this.reloadBridge();
} catch (error) {
logger.error(TAG, `reloadUpdate failed: ${getErrorMessage(error)}`);
throw Error(`switchVersion failed ${getErrorMessage(error)}`);
Expand All @@ -131,7 +142,7 @@ export class PushyTurboModule extends UITurboModule {
async restartApp(): Promise<void> {
logger.debug(TAG, ',call restartApp');
try {
await this.restartAbility();
await this.reloadBridge();
} catch (error) {
logger.error(TAG, `restartApp failed: ${getErrorMessage(error)}`);
throw Error(`restartApp failed ${getErrorMessage(error)}`);
Expand Down