Repository navigation
feat(dev): support external app previews with a shared Bun runtime - #78
Merged
Merged
Conversation
Add dev:file and dev:dir for apps outside the package checkout. Resolve the package and React from the checkout build while preserving inherited app aliases and the app's native Bun configuration. Return the lakehouse environment explicitly, watch imported app files, preserve URL filters when replacing the preview iframe, and recover from build errors without restarting the launcher. Include browser and directory consumer regressions. Co-authored-by: Sylvain Utard <sylvain.utard@gmail.com>
Export serveAppFile() from the Bun-only server/bun/preview entry so the CLI and checkout tooling can launch the same runtime. The caller supplies its lakehouse and dependency directory; the runtime owns bundling, imported-file watching, iframe reloads, SQL delivery, exports, and shutdown. Keep server entry points separate while sharing bounded body reads and reload channels. Share browser blob download cleanup. Preserve structured SQL rejections, recover missing relative and tsconfig-aliased imports, and refresh missed edits when the reload stream reconnects to the same server. Keep startup failure alerts over the full-screen iframe without host overflow. Bundle the existing tsconfig parser only into the Bun preview artifact. Browser consumers gain no installed dependencies or server implementation. Verify public workflows, packed exports, frontend isolation, and CLI usage.
Remove dependenciesFrom from serveAppFile(). Importing the preview entry already selects the runtime installation, so resolve the package and React relative to import.meta.dir. Update the checkout launcher, public consumer tests, packed-package check, and server guide. Verify packed CLI integration with the simplified API.
robinvrd
approved these changes
Oct 14, 2026
robinvrd
left a comment
Contributor
There was a problem hiding this comment.
LGTM, let's just verify running without credentials gives correct guidance for it to work
albert20260301
suggested changes
Oct 14, 2026
albert20260301
left a comment
There was a problem hiding this comment.
Blocking until CI is clean: the required source/package suite fails in dev:file replaces the rendered iframe and preserves URL filters after edits (the replacement iframe never renders Second preview). CodeQL also reports three new alerts in this PR, including one critical severity alert. Please resolve both and rerun the required checks before re-review.
Wait for rendered reload results instead of a one-second polling deadline. Keep preview connection logs free of environment values and fix the reconnect test proxy to its trusted upstream.
Validate credentials when constructing the local lakehouse and before serving local apps. Report required environment variables for direct credentials or a selected CLI proxy, and stop preview launchers before starting a server.
Merged
francoischalifour
pushed a commit
that referenced
this pull request
Oct 14, 2026
🤖 I have created a release *beep* *boop* --- ## [0.69.0](v0.68.0...v0.69.0) (2026-10-14) ### ⚠ BREAKING CHANGES * remove operation output parsers; data is what run returns ([#75](#75)) * **react:** catch missing filter bindings at compile time ([#67](#67)) * **react:** unify search, filters, and suggestions ([#66](#66)) * **react:** remove obsolete host skeleton APIs ([#63](#63)) ### Features * **dev:** support external app previews with a shared Bun runtime ([#78](#78)) ([a0af75c](a0af75c)) * **embed:** make bridge and query failures debuggable ([#76](#76)) ([a3bcf77](a3bcf77)) * **react:** add gradient scroll cues to horizontal tabs ([#73](#73)) ([446fced](446fced)) * **react:** unify search, filters, and suggestions ([#66](#66)) ([5fb5387](5fb5387)) * remove operation output parsers; data is what run returns ([#75](#75)) ([4411506](4411506)) ### Bug Fixes * **annotations:** restore widget targets, dismissal, and scrolling ([#64](#64)) ([71d6940](71d6940)) * **charts:** improve inspection, legends, and temporal axes ([#77](#77)) ([75852ad](75852ad)) * **charts:** use square corners for stacked bars ([#68](#68)) ([bb27ab9](bb27ab9)) * **react:** catch missing filter bindings at compile time ([#67](#67)) ([cc4d9ed](cc4d9ed)) * **react:** stretch widgets inside grid items ([#71](#71)) ([b8c5475](b8c5475)) * use full widget title width and official lakehouse SDK ([#70](#70)) ([51ae42a](51ae42a)) * widen app layouts and wrap grid rows sooner ([#72](#72)) ([fa9fa19](fa9fa19)) ### Code Refactoring * **react:** remove obsolete host skeleton APIs ([#63](#63)) ([2fa4efd](2fa4efd)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
Package contributors need to preview data apps outside this repository against the current checkout. This includes both a single-file app intended for hosted execution and a local app directory with its own Bun server.
The existing gallery is useful for package development, but it does not provide that workflow. External previews need to resolve the checkout’s package and React dependencies, preserve the app’s configuration, connect to the selected lakehouse, and recover reliably as files change.
The CLI needs the same single-file preview behavior. Putting the runtime in the package gives checkout tooling and the CLI one implementation for bundling, iframe hosting, SQL delivery, navigation, exports, and reloads. Launchers retain responsibility for installation, profiles, and credentials.
Closes #74 by exposing a real API instead of re-implementing in the Altertable CLI too.
External preview commands
Add two contributor commands:
bun run dev:file /absolute/path/index.tsx bun run dev:dir /absolute/path/app-directoryBoth resolve
@altertable/data-appand React from the checkout build, allowing external apps to run without installing the package themselves. They build the package ifdistis absent; subsequent package source changes requirebun run build.dev:filelaunches the shared preview runtime. It bundles the app for browser execution and renders it through the existing sandboxed iframe bridge.dev:dirruns the app’s ownsrc/server.tswith Bun’s watch mode. A temporary, typed TypeScript configuration combines the app’s inherited aliases with checkout package paths. Checkout mappings take precedence, while the app’s original configuration andbunfig.tomlremain in use.Lakehouse setup returns a normalized environment and a description of the selected connection without mutating
process.env. A CLI proxy takes precedence over direct credentials.Shared Bun preview API
Expose the runtime through a dedicated entry:
fileidentifies the app source. The port defaults to25837;0selects an available port.The ownership boundary is explicit:
The host supports URL-backed navigation and CSV/ZIP downloads through existing bridge contracts. App edits replace the iframe while preserving host URL filters. Bundles include inline source maps and injected app styles.
Reliable reloads and recovery
Watch imported app files through their directories so editor saves that rename files still trigger rebuilds. Exclude package build files and
node_modulesfrom app watching.Capture dependencies before parsing and observe candidate import directories before resolution. This lets an initially broken preview recover when an imported file is fixed or a missing target is created, including relative imports and TypeScript aliases outside the entry directory.
Failed builds retain earlier watcher directories because parsing may stop before rediscovering the full dependency graph. Successful builds prune obsolete watches. Rebuilds are debounced and serialized.
The host refreshes the bundle on every SSE
readyevent, catching edits missed while disconnected. A changed server session triggers a full-page reload. Concurrent bundle fetches only apply the latest response, and build or fetch failures appear in the host.Focused shared helpers
Share three private helpers where there are existing consumers:
downloadBlob()helper for standalone CSV exports and preview-host downloads.Server entry points remain separate. Callers retain their routing, authorization, response formats, watchers, and debounce behavior.
Runtime and dependency boundaries
The preview server binds to
127.0.0.1, validates the request host, and accepts SQL only from its own origin. SQL requests have a 100,000-byte UTF-8 body limit. Oversized requests return a JSONquery_rejectedresponse so the host preserves the typed error.Preview functionality is exported only through the Bun subpath. Browser entries remain free of Bun/server implementations and credentials. Production dependencies are unchanged.
get-tsconfigremains a development dependency and is bundled into the Bun preview artifact. It preserves JSONC, inherited configuration,baseUrl, and wildcard mappings without introducing a custom configuration parser or an installed frontend dependency.Release coordination
The companion CLI change consumes this API as a thin launcher. We need to publish a package version containing the preview entry before updating the CLI’s pinned package version.