feat: add abstract local peer communication - #561
Conversation
|
@coderabbitai review |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds ESP32 local peer messaging with discovery, reliable sends, broadcasts, subscriptions, framing, encryption, runtime lifecycle handling, and a role-based example. It also adds offline Wi-Fi setup and preference clearing flows, documentation, tests, manifest wiring, and smoke-test tooling updates. ChangesLocal peer communication
Offline Wi-Fi setup and preferences
Smoke tooling
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (1)
firmware/host/app/runtime-context.ts (1)
489-495: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winPreserve future capability extensions by avoiding hardcoded destructuring.
If new fields (e.g.,
bluetooth) are added toConnectivityCapabilityin the future, the current implementation will silently drop them by only copyingnetwork. Returning the object directly whenlocalPeeris missing, and spreading...connectivitywhen wrapping it, makes the factory resilient to future extensions.♻️ Proposed refactor
private createConnectivityCapability(connectivity: ConnectivityCapability): ConnectivityCapability { const localPeer = connectivity.localPeer - if (!localPeer) return { network: connectivity.network } + if (!localPeer) return connectivity const context = this return { - network: connectivity.network, + ...connectivity, localPeer: {🤖 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 `@firmware/host/app/runtime-context.ts` around lines 489 - 495, Update createConnectivityCapability to preserve all existing ConnectivityCapability fields: return connectivity directly when localPeer is absent, and spread ...connectivity when constructing the wrapped result before overriding localPeer. Keep the current localPeer wrapping behavior unchanged.
🤖 Prompt for all review comments with 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.
Inline comments:
In `@firmware/host/modules/connectivity/__tests__/local-peer-frame.test.ts`:
- Around line 20-24: Update the hash assertion in the “local peer UTF-8 codec
round-trips ASCII, Japanese, and supplementary characters” test to compare
fnv1a32(value) against a precomputed known FNV-1a expected value, rather than
invoking fnv1a32 on the same input on both sides. Keep the existing UTF-8
round-trip assertion unchanged.
In `@firmware/host/modules/connectivity/__tests__/local-peer-service.test.ts`:
- Around line 6-261: Move the runtime-focused tests in
firmware/host/modules/connectivity/__tests__/local-peer-service.test.ts (lines
6-261), including FakeRadioNetwork, FakeRadio, openPair, and the
LocalPeerService lifecycle/retry cases, into XS-driven Moddable coverage while
preserving their behaviors. Replace the source/manifest rescanning assertions in
firmware/host/modules/connectivity/__tests__/local-peer.architecture.ts (lines
1-35) with runtime checks, or document the architectural rationale with
source-level why-comments instead.
In `@firmware/host/modules/connectivity/__tests__/stored-wifi.test.ts`:
- Around line 121-137: Move the clearStoredWiFiCredentials behavior test from
the Node suite into the XS-driven Moddable harness, preserving its setup and
network-stop assertions. In the migrated test, directly verify that both stored
preference keys, wifi.ssid and wifi.password, are empty after clearing; do not
rely solely on connectStoredWiFi() returning false.
In `@firmware/host/modules/connectivity/esp32/local-peer-radio.c`:
- Around line 144-155: The callbacks around the shown send-status handler and
the callback covering lines 164–207 must synchronize access to gLocalPeerRadio
with localPeerNativeClose. Hold the same close/lookup lock while reading the
global, checking radio->closed, and incrementing useCount, then release it
before posting or other callback work; ensure no radio fields are dereferenced
before the reference is acquired.
In `@firmware/host/modules/connectivity/esp32/local-peer-radio.js`:
- Around line 23-32: Update the construction error path in the local peer radio
initialization to roll back the native radio after nativeConstruct succeeds but
nativeGetID fails. In the catch block surrounding nativeConstruct and
nativeGetID, release or reset the native object and clear the occupied
gLocalPeerRadio state before closing Wi-Fi and rethrowing the original error.
In `@firmware/host/modules/connectivity/local-peer-service.ts`:
- Around line 542-552: In the reliable-message handling flow around `#deliver` and
`#sendAcknowledgement`, queue and complete the acknowledgement before invoking
subscribers via `#deliver`, while preserving duplicate suppression and existing
acknowledgement behavior. Ensure a synchronous close() from a subscriber cannot
interrupt ACK completion, and add a regression test covering close() from the
message handler without causing a sender timeout.
In `@web/preference/index.html`:
- Around line 88-90: Update the catch block handling the save-status failure so
null or undefined rejection values do not cause a second exception when reading
error.message. Safely derive the displayed error detail before calling
setStatus, while preserving the existing message and error status for ordinary
Error objects.
In `@web/web-ui.test.mjs`:
- Around line 41-50: Replace the source-text regex assertions in the preference
test with a runtime interaction test that loads the preference page, stubs
confirmation and client.send, and clicks the wifi-clear-button. Assert the
resulting _batch payload, cleared SSID/password fields, success status, and
recovery of the button’s disabled state; retain only assertions that verify
actual rendered behavior.
---
Nitpick comments:
In `@firmware/host/app/runtime-context.ts`:
- Around line 489-495: Update createConnectivityCapability to preserve all
existing ConnectivityCapability fields: return connectivity directly when
localPeer is absent, and spread ...connectivity when constructing the wrapped
result before overriding localPeer. Keep the current localPeer wrapping behavior
unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 15a03c36-4abb-4299-8d76-1f9d481484fb
📒 Files selected for processing (31)
firmware/docs/local-peer-communication_ja.mdfirmware/host/app/boot-services.tsfirmware/host/app/capabilities.tsfirmware/host/app/runtime-context.tsfirmware/host/app/setup-mode.tsfirmware/host/modules/connectivity/__tests__/local-peer-frame.test.tsfirmware/host/modules/connectivity/__tests__/local-peer-service.test.tsfirmware/host/modules/connectivity/__tests__/local-peer.architecture.tsfirmware/host/modules/connectivity/__tests__/stored-wifi.test.tsfirmware/host/modules/connectivity/esp32/local-peer-radio.cfirmware/host/modules/connectivity/esp32/local-peer-radio.jsfirmware/host/modules/connectivity/local-peer-capability.tsfirmware/host/modules/connectivity/local-peer-codec.tsfirmware/host/modules/connectivity/local-peer-frame.tsfirmware/host/modules/connectivity/local-peer-radio-types.tsfirmware/host/modules/connectivity/local-peer-service.tsfirmware/host/modules/connectivity/local-peer-types.tsfirmware/host/modules/connectivity/manifest.jsonfirmware/host/modules/connectivity/manifest_wasm.jsonfirmware/host/modules/connectivity/sim/local-peer-capability.tsfirmware/host/modules/connectivity/stored-wifi.tsfirmware/host/modules/ui/views/settings/__tests__/settings-view/settings-view.test.tsfirmware/host/modules/ui/views/settings/settings-view.tsfirmware/mods/README_ja.mdfirmware/mods/examples/local_peer_hello/README_ja.mdfirmware/mods/examples/local_peer_hello/manifest.jsonfirmware/mods/examples/local_peer_hello/mod.jsfirmware/tsconfig.test.jsonweb/preference/index.htmlweb/preference/preference.cssweb/web-ui.test.mjs
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7b7feb1c5f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
🧹 Nitpick comments (1)
firmware/scripts/smoke-lin.sh (1)
74-75: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAvoid globally disabling
errexit.Disabling
errexitwithset +eallows the script to continue running if thetimeoutcommand fails, which can inadvertently mask failures if there are subsequent commands, or skip configuredERRtraps.If you need to handle
timeout's exit code (for instance, if returning124for a timeout is an expected condition) without terminating the script viaset -e, it is safer to handle the failure explicitly.♻️ Proposed refactor to explicitly handle the exit status
-set +e -timeout "$smoke_timeout" env XSBUG_HOST="$xsbug_host" XSBUG_PORT="$xsbug_port" xvfb-run -a "$MODDABLE/build/bin/lin/release/mcsim" "$smoke_build_root/bin/$platform_path/debug/app/mc.so" +timeout "$smoke_timeout" env XSBUG_HOST="$xsbug_host" XSBUG_PORT="$xsbug_port" xvfb-run -a "$MODDABLE/build/bin/lin/release/mcsim" "$smoke_build_root/bin/$platform_path/debug/app/mc.so" || exit_code=$? +# You can optionally evaluate $exit_code here if needed🤖 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 `@firmware/scripts/smoke-lin.sh` around lines 74 - 75, Remove the global set +e before the timeout invocation in the smoke script. Update the command handling around timeout in the smoke execution flow to explicitly capture and evaluate its exit status, preserving the intended timeout behavior without bypassing errexit or configured ERR traps.Source: Linters/SAST tools
🤖 Prompt for all review comments with 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.
Nitpick comments:
In `@firmware/scripts/smoke-lin.sh`:
- Around line 74-75: Remove the global set +e before the timeout invocation in
the smoke script. Update the command handling around timeout in the smoke
execution flow to explicitly capture and evaluate its exit status, preserving
the intended timeout behavior without bypassing errexit or configured ERR traps.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: db20dfba-56f4-4cbb-998e-cb35ac2fd2af
📒 Files selected for processing (20)
firmware/host/app/capabilities.tsfirmware/host/app/runtime-context.tsfirmware/host/modules/connectivity/__tests__/local-peer-frame.test.tsfirmware/host/modules/connectivity/__tests__/local-peer-service-xs/local-peer-service-xs.test.tsfirmware/host/modules/connectivity/__tests__/local-peer-service-xs/manifest.test.jsonfirmware/host/modules/connectivity/__tests__/stored-wifi-xs/manifest.test.jsonfirmware/host/modules/connectivity/__tests__/stored-wifi-xs/stored-wifi-xs.test.tsfirmware/host/modules/connectivity/__tests__/stored-wifi.test.tsfirmware/host/modules/connectivity/esp32/local-peer-radio.cfirmware/host/modules/connectivity/esp32/local-peer-radio.jsfirmware/host/modules/connectivity/local-peer-capability.tsfirmware/host/modules/connectivity/local-peer-service.tsfirmware/host/modules/connectivity/local-peer-types.tsfirmware/host/modules/connectivity/manifest.jsonfirmware/scripts/run-module-tests.jsfirmware/scripts/smoke-lin.shfirmware/scripts/xsbug-log-smoke-server.jsweb/preference/index.htmlweb/preference/preference.mjsweb/web-ui.test.mjs
💤 Files with no reviewable changes (1)
- firmware/host/modules/connectivity/tests/stored-wifi.test.ts
🚧 Files skipped from review as they are similar to previous changes (8)
- firmware/host/modules/connectivity/local-peer-capability.ts
- firmware/host/modules/connectivity/tests/local-peer-frame.test.ts
- firmware/host/modules/connectivity/local-peer-types.ts
- firmware/host/app/capabilities.ts
- firmware/host/app/runtime-context.ts
- firmware/host/modules/connectivity/esp32/local-peer-radio.js
- firmware/host/modules/connectivity/local-peer-service.ts
- firmware/host/modules/connectivity/esp32/local-peer-radio.c
# Conflicts: # firmware/scripts/smoke-lin.sh
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
# Conflicts: # firmware/host/app/setup-mode.ts # firmware/host/modules/ui/views/settings/__tests__/settings-view/settings-view.test.ts # firmware/host/modules/ui/views/settings/settings-view.ts
Summary
LocalPeerCapabilityAPI.hello world Nwith bounded and sanitized receiver balloons), plus architecture checks, unit tests, and Moddable runtime tests.LocalPeerErrorpreload-safe and queueing acknowledgements before subscriber replies.Why
Modules need a local P2P communication surface without depending on ESP-NOW or another transport-specific API. This change exposes only logical peers, sessions, messages, and delivery receipts, so the underlying transport can be replaced without changing module code.
Validation
npm run test:unit: 179 tests passednpm run lintnpm run formatnpm run check:architecture: 60 checks passedesp32/m5stackchan_cores3andesp32/m5stack_cores3Summary by CodeRabbit
New Features
Documentation
Bug Fixes