Skip to content

Support Vite descriptors and Expo mobile hosts#73

Open
mickmister wants to merge 36 commits into
mainfrom
vk/e560-vd-mobile-app
Open

Support Vite descriptors and Expo mobile hosts#73
mickmister wants to merge 36 commits into
mainfrom
vk/e560-vd-mobile-app

Conversation

@mickmister
Copy link
Copy Markdown
Member

@mickmister mickmister commented May 14, 2026

Summary

This PR advances the Springboard Vite migration and adds the shared Expo/React Native building blocks needed by SongDrive and Vibe Dashboard mobile apps.

What changed

  • Refactored the Springboard Vite plugin/dev flow around a single-port Vite + ModuleRunner setup.
    • Serves generated web/node entries through Vite transforms.
    • Installs Vite middleware before the SPA fallback.
    • Stores generated Vite files under node_modules and removes older unused plugin/config utilities.
    • Adds coverage for dev-route HMR behavior around registerServerModule.
  • Added Springboard descriptor APIs for app composition.
    • Introduces springboard.defineModule(...) and springboard.entrypoint(...) so apps can declare modules/entrypoints without manually typing registry objects.
    • Supports async entrypoint composition and updates create-springboard examples/tests to use the descriptor style.
  • Added Expo/React Native support primitives.
    • Adds an Expo WebView host component, bundled web asset loader, native module typings, auth-session helper, and push notification hook.
    • Updates the React Native entrypoint plumbing and package exports so app repos can share this boilerplate instead of duplicating it in each mobile app.
  • Updates Springboard package exports, local publish tooling, and the lockfile for the new Vite/mobile dependencies.

Why

SongDrive is migrating from esbuild to Vite while continuing to support browser, server, and mobile app entrypoints. Vibe Dashboard also uses Springboard and is adding an Expo mobile shell. These changes move the common Vite and React Native boilerplate into Springboard so both apps can share the same app framework conventions and avoid project-specific copies of mobile host logic.

Implementation notes

  • The descriptor API is the preferred convention for app entrypoints/modules going forward; it keeps browser/webview modules separate from native React Native host modules.
  • The Expo host owns the native RN <-> WebView transport while the web Springboard app can be bundled independently for mobile assets.
  • The Vite plugin cleanup keeps generated runtime entries centralized and makes dev-server HMR behavior explicit and test-covered.

Vibe Kanban added 23 commits February 25, 2026 17:12
…t and configurable port` in `76d916a`.

I left [`apps/vite-test/src/tic_tac_toe.tsx`](/var/tmp/vibe-kanban/worktrees/8100-fix-vite-dev-nod/springboard/apps/vite-test/src/tic_tac_toe.tsx) unstaged, since it was modified but not included in your list.
…es` in `6a8c1c4`.

I left the untracked `.springboard/` directory out of the commit, as requested by your file list.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 14, 2026

Deploying jamtools-docs-new with  Cloudflare Pages  Cloudflare Pages

Latest commit: 635ba86
Status: ✅  Deploy successful!
Preview URL: https://74197178.jamtools-docs-new.pages.dev
Branch Preview URL: https://vk-e560-vd-mobile-app.jamtools-docs-new.pages.dev

View logs

@claude
Copy link
Copy Markdown

claude Bot commented May 14, 2026

Claude finished @mickmister's task —— View job


PR Review: Continue vite migration for mobile app support

This is a substantial PR that migrates springboard from esbuild to Vite while adding comprehensive mobile app support. I've completed a thorough review of the changes.

Review Checklist:

  • Read repository guidelines (CLAUDE.md)
  • Analyze new React Native/Expo components and services
  • Review vite-plugin architecture changes
  • Check test coverage and quality
  • Evaluate security considerations
  • Assess performance implications
  • Review code quality and best practices
  • Provide comprehensive feedback

Overall Assessment

Strong Points:

  • Well-structured multi-platform architecture with clean separation of concerns
  • Comprehensive React Native/Expo integration with proper TypeScript support
  • Good test coverage including E2E tests for HMR functionality
  • Proper error handling and async patterns throughout

Areas of Concern:
Several security, performance, and reliability issues need attention before merge.


Detailed Findings

🔒 Security Issues

High Priority:

  1. WebView Security Configuration (packages/springboard/src/platforms/react-native/components/expo_springboard_webview_host.tsx:121-137)

    originWhitelist={['*']}  // ❌ Too permissive
    allowUniversalAccessFromFileURLs={true}  // ❌ Potential security risk
    allowFileAccessFromFileURLs={true}  // ❌ Could allow file access attacks

    Risk: These overly permissive settings could allow malicious content to access local files or bypass origin policies.

    Recommendation: Implement a restrictive whitelist and disable unnecessary file access permissions.

  2. JavaScript Injection Pattern (expo_springboard_webview_host.tsx:47,73)

    webViewRef.current?.injectJavaScript(`window.receiveMessageFromRN(${JSON.stringify(message)});`);
    webViewRef.current?.injectJavaScript(`window.spaNavigate("${props.spaRoute.route}"); true;`);

    Risk: Direct string interpolation could lead to script injection if route contains malicious content.

    Recommendation: Use proper escaping or postMessage API instead of string interpolation.

⚡ Performance Concerns

Medium Priority:

  1. Push Notification Setup (packages/springboard/src/platforms/react-native/hooks/use_expo_push_notifications.tsx:91-98)

    useEffect(() => {
        registerForPushNotificationsAsync(latestProps.current)
            .then(token => {
                if (token) {
                    void latestProps.current.onTokenFetched(token); // ❌ Unhandled promise
                }
            })
            .catch((error: unknown) => latestProps.current.onTokenError(String(error)));
    }, []);  // ❌ No dependencies

    Issues:

    • Unhandled async operations
    • Empty dependency array may cause stale closures

    Recommendation: Handle the promise properly and add necessary dependencies.

  2. WebView Reload Strategy (expo_springboard_webview_host.tsx:142-144)

    onContentProcessDidTerminate={() => {
        webViewRef.current?.reload();  // ❌ Unconditional reload
    }}

    Risk: Could cause infinite reload loops if there's a persistent issue.

    Recommendation: Implement exponential backoff or error tracking.

🏗️ Architecture & Code Quality

Medium Priority:

  1. Vite Plugin Architecture (packages/springboard/vite-plugin/src/index.ts)

    • Good: Well-structured unified plugin approach replacing multiple smaller plugins
    • Good: Proper TypeScript support with comprehensive type definitions
    • ⚠️ Concern: Complex request handling logic could benefit from more granular testing
  2. Missing Type Safety (expo_auth_session_helper.ts:62)

    void (options.openExternalUrl || Linking.openURL)(options.url);

    Issue: Type assertion without validation could fail at runtime.

    Recommendation: Add proper type guards or default handling.

🧪 Test Coverage

Good Coverage:

  1. E2E Testing (tests/e2e/vite-dev-server-route-hmr.test.ts)
    • Excellent: Comprehensive test for HMR functionality
    • Good: Proper cleanup and error handling in tests
    • Good: Realistic test scenarios with proper timing controls

Missing Coverage:

  • React Native component testing (no tests for SpringboardExpoWebViewHost)
  • Auth session helper edge cases
  • Push notification error scenarios

📱 Mobile-Specific Considerations

Well Implemented:

  1. Asset Loading (expo_bundled_web_asset_loader.ts)

    • Good: Proper async asset loading with error handling
    • Good: Support for custom HTML transformations
  2. Navigation Handling (expo_springboard_webview_host.tsx:158-174)

    • Good: Proper Android back button integration
    • Good: WebView navigation state management

🚀 Performance Optimizations

Recommendations:

  1. Bundle Size Impact
    • The addition of multiple Expo dependencies significantly increases bundle size
    • Consider lazy loading these modules only when needed
    • Document the impact on bundle size in mobile vs web builds

Recommendations for Next Steps

Before Merge (Critical):

  1. Fix WebView security settings - restrict permissions and whitelist
  2. Secure JavaScript injection - use postMessage or proper escaping
  3. Handle async operations - properly await push notification setup
  4. Add error boundaries - prevent crash loops in WebView components

Post-Merge (Important):

  1. Add comprehensive React Native component tests
  2. Document security considerations for WebView usage
  3. Create performance benchmarks for mobile vs web builds
  4. Consider implementing progressive loading for Expo features

Summary

This PR represents excellent architectural progress toward Vite migration and mobile support. The code quality is generally high with good separation of concerns and comprehensive TypeScript support. However, security issues with WebView configuration and JavaScript injection must be addressed before merge to prevent potential vulnerabilities.

The E2E testing approach is exemplary and the overall structure sets up the codebase well for multi-platform development.


Recommendation: 🔄 Request Changes - Address security concerns before approval

@mickmister mickmister changed the title Continue vite migration for mobile app support Support Vite descriptors and Expo mobile hosts May 14, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f2559ab4fa

ℹ️ 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".

clearRegisteredSplashScreen();
resetServerRegistry();

await import('__USER_ENTRY__');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Register exported descriptor in node dev bootstrap

The dev server bootstrap only executes await import('__USER_ENTRY__'), so descriptor-style entrypoints (export default springboard.defineModule(...) / springboard.entrypoint(...)) never get registered before engine.initialize(). In that case the Node dev app starts with no modules/routes despite the new descriptor API, which breaks the migration path in serve mode. Mirror the production bootstrap by reading module exports and calling engine.registerDescriptor(...).

Useful? React with 👍 / 👎.

const rpc = new BrowserJsonRpcClientAndServer(`${WS_HOST}/ws`);
const remoteKvStore = new HttpKvStoreClient(DATA_HOST);
const userAgentKvStore = new BrowserKVStoreService(localStorage);
const applicationDescriptor = getApplicationDescriptorFromExports(applicationEntrypointModule, '__USER_ENTRY__');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Allow legacy side-effect entrypoints in web bootstrap

This unconditionally requires a descriptor export and throws when the app entrypoint only uses side-effect registration (for example existing springboard.registerModule(...) files). The previous flow supported those modules by importing them directly; now browser startup fails at runtime for legacy apps that have no default/entrypoint export. Keep descriptor support, but fall back to side-effect initialization when no descriptor export is present.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant