Skip to content

Add runtime capability introspection API#166

Merged
devallibus merged 2 commits intomasterfrom
feat/runtime-capabilities-introspection
Mar 6, 2026
Merged

Add runtime capability introspection API#166
devallibus merged 2 commits intomasterfrom
feat/runtime-capabilities-introspection

Conversation

@devallibus
Copy link
Owner

Summary

  • add a generic getRuntimeInfo() API to webtau/core
  • extend provider metadata so runtimes can expose stable capability flags
  • surface Electrobun render-mode capabilities through the generic runtime API
  • update the Electrobun example and base scaffold to use runtime/capability branching
  • add tests and CI coverage for the new runtime introspection path

What changed

  • webtau/core now exports getRuntimeInfo() plus RuntimeInfo / RuntimeCapabilities types
  • CoreProvider now supports optional runtimeInfo
  • Tauri and Electrobun providers populate runtime metadata
  • the Electrobun counter example now reads render mode from getRuntimeInfo() instead of adapter-specific helpers
  • the base scaffold now exposes runtime/render mode through document.body.dataset
  • CI typechecks examples/electrobun-counter

Validation

  • bun test packages/webtau/src/core.test.ts packages/webtau/src/adapters/electrobun.test.ts
  • bun test packages/create-gametau/src/cli.test.ts
  • bun run test in examples/electrobun-counter
  • bunx tsc --noEmit -p packages/webtau/tsconfig.json
  • bunx tsc --noEmit -p packages/create-gametau/tsconfig.json
  • bunx tsc --noEmit -p examples/electrobun-counter/tsconfig.json
  • bun run build:web in examples/electrobun-counter
  • bun run build:electrobun:hybrid in examples/electrobun-counter
  • bun run build:electrobun:gpu in examples/electrobun-counter

Tracking

@devallibus
Copy link
Owner Author

PR Review — claude-opus-4-6 (Claude Opus 4.6, 1M context)

Overall

Well-designed API addition. getRuntimeInfo() gives apps a single, generic entry point for runtime/capability introspection instead of importing adapter-specific helpers. The type system, fallback chain, and test coverage are solid.

Verdict: Approve with observations.


Strengths

  • Clean type layering: RuntimeCapabilities has required universal flags (events, fs, dialog, window, task, convertFileSrc) and optional runtime-specific extensions (renderMode?, hasGpuWindow?, etc.). This means consumers can branch on universal capabilities without knowing which runtime they're on, and opt-in to runtime-specific fields when needed.

  • RuntimeInfoResolver (RuntimeInfo | (() => RuntimeInfo)): Supporting both static and lazy resolution is the right call — Electrobun capabilities can change after initial bootstrap, and the function form lets providers defer reads until getRuntimeInfo() is actually called.

  • Backwards-compatible: CoreProvider.runtimeInfo is optional. Existing providers work unchanged — deriveRuntimeInfo() falls back to id-based heuristics when runtimeInfo isn't supplied.

  • cloneRuntimeInfo(): Shallow-cloning both the top-level object and capabilities before returning prevents callers from mutating internal state. Good defensive practice.

  • normalizeElectrobunRenderMode() allowlist: Only "browser", "hybrid", "gpu" pass through; anything else becomes "unknown". Prevents downstream consumers from relying on arbitrary string values.

  • Test coverage: 4 tests covering WASM default, Tauri auto-detection, explicit custom provider, and Electrobun bridge derivation. The Electrobun test exercises the fallback path (provider without runtimeInfo), which is the most complex derivation chain.

  • Scaffold integration: document.body.dataset.runtime and document.body.dataset.renderMode in the base template is a nice touch — enables CSS selectors like [data-runtime="electrobun"] with zero JS ceremony.

  • CI: Adding bunx tsc --noEmit -p examples/electrobun-counter/tsconfig.json catches type errors in the example that previously would have gone unnoticed.


Observations

  1. Dual Electrobun capability derivationcore.ts:getElectrobunBridgeCapabilities() and electrobun.ts:getElectrobunRuntimeCapabilities() both derive capabilities from the Electrobun bridge, but through different type interfaces (ElectrobunRuntimeBridge vs ElectrobunBridge) and with slightly different logic. The core.ts version normalizes renderMode and derives hasGpuWindow/hasWgpuView/hasWebGpu from it; the electrobun.ts version passes renderMode through as-is. The layering is defensible (core.ts is best-effort fallback for bare providers, adapter provides authoritative data), but if either changes independently they could diverge. Worth a brief comment in core.ts noting this is the fallback path.

  2. No test for function-form RuntimeInfoResolverderiveRuntimeInfo() handles typeof provider.runtimeInfo === "function" but all 4 tests supply static runtimeInfo objects. A small test registering a provider with runtimeInfo: () => ({ ... }) would exercise that branch cheaply.

  3. wasmCapabilities and tauriCapabilities are identical — Both declare all 6 boolean flags as true. Having them as separate constants is correct for future divergence, but they're currently identical. Not a problem, just noting it.

  4. CRLF → LF normalizationcore.ts and provider.ts show full-file diffs because line endings were normalized from \r\n to \n. The actual logical change is ~50 new lines. Consider a .gitattributes with *.ts text eol=lf to prevent this from recurring and inflating future diffs.

  5. getRuntimeInfo() not cached — Each call re-derives from the provider or environment. For the current use case (called once at startup) this is fine, but if it ever gets called in a hot path, the allocation from cloneRuntimeInfo() on every call could add up. Non-issue today, just noting the design choice.


No Issues Found

  • No security concerns — document.body.dataset is set from internal state, not user input.
  • The getElectrobunCapabilities() import is correctly removed from the example since getRuntimeInfo() now provides the same data through the generic API.
  • The auto-registered Tauri provider in invoke() now includes runtimeInfo, keeping the auto-detection and explicit-registration paths consistent.

LGTM.


Reviewed by claude-opus-4-6 (Claude Opus 4.6, 1M context)

@devallibus devallibus merged commit fb17d65 into master Mar 6, 2026
9 checks passed
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.

[P1] Electrobun: expose render-mode capabilities to app code and templates

1 participant