feat(devframe): remote client assets — serve SPA dists through a caching CDN back-proxy - #236
Open
antfubot wants to merge 5 commits into
Open
feat(devframe): remote client assets — serve SPA dists through a caching CDN back-proxy#236antfubot wants to merge 5 commits into
antfubot wants to merge 5 commits into
Conversation
…ing CDN back-proxy
Every static-assets seam (cli.distDir, hostStatic, mountStatic, the
serve-static engine) now accepts a version-locked RemoteAssets
declaration ({ package, version }) alongside a local directory, so a
plugin's browser bundle can live in its own npm package instead of
shipping inside the node tarball.
Resolution order per request: a locally installed copy of the assets
package (resolved from the declaration's resolveFrom, warning on
minor/patch skew and rejecting a major mismatch), the per-file cache
under <project storage>/.remote-assets/<pkg>@<version>/, then the CDN
provider (jsdelivr by default, unpkg or a custom mirror via provider) —
streaming through to the browser while teeing into the cache. Request
paths resolve against the provider's file listing (correct 404s and SPA
fallback), degrading to per-file probing when the listing is
unreachable. HTML navigations that cannot be satisfied get a styled
error page pointing at the local-install fix; static builds materialize
the full file set so their output stays self-contained.
New diagnostics DF0058–DF0063 cover listing/fetch/cache/materialization
failures and version skew, each with a docs page.
✅ Deploy Preview for devfra ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
…sets # Conflicts: # docs/errors/DF0058.md # packages/devframe/src/node/diagnostics.ts # packages/devframe/src/node/host-h3.ts # tests/__snapshots__/tsnapi/devframe/adapters/build.snapshot.d.ts # tests/__snapshots__/tsnapi/devframe/index.snapshot.d.ts # tests/__snapshots__/tsnapi/devframe/internal.snapshot.d.ts # tests/__snapshots__/tsnapi/devframe/types.snapshot.d.ts
Collapse the remote-assets module's public API from eight exports to one (resolveStaticAssetsSource) — cache-path helpers, createRemoteAssetsStore, resolveInstalledRemoteAssets, and the store options interfaces are now private, and the error page moves into serve-static as an internal helper. resolveStaticAssetsSource takes the project storage dir directly (dropping the options object), so every call site loses the cacheRoot plumbing; the build adapter reuses it too instead of hand-rolling install/materialize. RemoteAssetsStore.serve now returns a web Response, letting serve-static drop the RemoteAssetsServedFile / RemoteAssetsServeOptions types and the bespoke miss/stream/cancel handling. Net ~370 fewer lines.
The installed-package resolution returns pathe (forward-slash) paths, but the tests built the expected distDir with node:path — backslashes on Windows — so the equality assertions failed only on windows-latest. Compare both sides normalized to forward slashes.
A remote source's `package` and `version` are interpolated into CDN URLs and the on-disk cache path, so `resolveStaticAssetsSource` now rejects a value that isn't a valid npm package name / exact semver version (new `DF0065`) — closing off malformed URLs and cache-path traversal (e.g. a `..` version segment).
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.
What
Lets a devframe's browser assets live in their own npm package instead of shipping inside the node tarball: every static-assets seam —
cli.distDir,hostStatic,mountStatic, and the shared serve-static engine — now accepts a version-lockedRemoteAssetsdeclaration ({ package, version }) alongside a local directory, served through an on-demand, caching CDN back-proxy.Why
~91% of the published bytes across the asset-shipping packages (~19.7 MB of 21.6 MB) is prebuilt browser assets —
@devframes/plugin-gitalone carries a 12.2 MB client. This core seam is the first step toward slim node packages with lockstep-published-clientasset packages, with no extra install required in the happy path and a zero-network story for air-gapped setups.How it resolves (per request, version-locked)
resolveFrom(import.meta.url), sonpm i <pkg>-clientserves with zero network. Minor/patch skew warns (DF0061); a major mismatch throws (DF0060).<project storage>/.remote-assets/<pkg>@<version>/.jsdelivr(default),unpkg, or a custom mirror; the file streams through to the browser while being teed into the cache.Request paths resolve against the provider's file listing (correct 404s + SPA fallback), degrading to per-file probing when the listing API is down (
DF0058). HTML navigations that can't be satisfied render a styled error page with the local-install fix; other requests get a plain 502 (DF0059). Static builds (createBuild) materialize the full file set from the listing so their output stays self-contained (DF0063).Surface
devframe/utils/remote-assets:resolveStaticAssetsSource(),createRemoteAssetsStore(),resolveInstalledRemoteAssets(), cache-path helpers, error page.RemoteAssets,StaticAssetsSource,RemoteAssetsStore, provider types.cli.distDir,InitDevframeOptions.distDir,CreateDevServerOptions.distDir,CreateBuildOptions.distDir,DevframeViewHost.hostStatic,DevframeHost.mountStatic,serveStaticHandler/mountStaticHandler/serveStaticNodeMiddleware.DF0058–DF0063withdocs/errors/pages.installDevframe,@devframes/vitestatic mount,@devframes/nexthost.API snapshots updated accordingly (input-widening;
DevframeHost.mountStaticimplementors now also receive stores — acceptable pre-1.0).Out of scope (follow-ups)
-clientpackages.json-render-uirenderer-module seam.Created with the help of an agent.