new ViteExtension(): Vite's dev server in DEV; otherwise the build served from the classpath (flash-vite/, directory or jar, no manifest) as an SPA. Overrides: root, devPort, basePath, navigationOnly.
The plugin (build goal at prepare-package) installs, builds, packages dist/ and gzips text files at maximum compression, so mvn package makes a jar that serves its own frontend and mvn test needs no Node.
Serving: hashed assets/ immutable, the rest revalidated by ETag, HEAD with the real length, 304 with its headers, gzip honouring q=0; a miss is index.html only for a browser navigation (Sec-Fetch-Mode: navigate or Accept: text/html), otherwise the app's 404. Headers pre-encoded and request headers read in place: nothing allocated per request.
Core: Response.type(byte[]) and Request.headerView(name).
1,535 lines of main code become 475 plus 108 for the plugin; the Jackson dependency is gone. Docs: flash-extensions/flash-ext-vite/docs/README.md.
flash-ext-data: TxManager is AutoCloseable and DataExtension closes it on stop, so a stopped app releases its connection pool (Hibernate's handed-in data source included).
Tests: flash core 711, data-jdbc 19, data-hibernate 20, vite 14, plugin 2. Verified end to end on Glossa: plain mvn package, then java -jar alone serves the SPA. Mixed routing checked by hand on FastPathRouter.
One release for both changes.
**flash-ext-vite + flash-ext-vite-maven-plugin** replace `flash-ext-web-bundler`.
- `new ViteExtension()`: Vite's dev server in DEV; otherwise the build served from the classpath (`flash-vite/`, directory or jar, no manifest) as an SPA. Overrides: `root`, `devPort`, `basePath`, `navigationOnly`.
- The plugin (`build` goal at `prepare-package`) installs, builds, packages `dist/` and gzips text files at maximum compression, so `mvn package` makes a jar that serves its own frontend and `mvn test` needs no Node.
- Serving: hashed `assets/` immutable, the rest revalidated by ETag, HEAD with the real length, 304 with its headers, gzip honouring `q=0`; a miss is `index.html` only for a browser navigation (`Sec-Fetch-Mode: navigate` or `Accept: text/html`), otherwise the app's 404. Headers pre-encoded and request headers read in place: nothing allocated per request.
- Core: `Response.type(byte[])` and `Request.headerView(name)`.
- 1,535 lines of main code become 475 plus 108 for the plugin; the Jackson dependency is gone. Docs: `flash-extensions/flash-ext-vite/docs/README.md`.
**flash-ext-data**: `TxManager` is `AutoCloseable` and `DataExtension` closes it on stop, so a stopped app releases its connection pool (Hibernate's handed-in data source included).
Tests: flash core 711, data-jdbc 19, data-hibernate 20, vite 14, plugin 2. Verified end to end on Glossa: plain `mvn package`, then `java -jar` alone serves the SPA. Mixed routing checked by hand on FastPathRouter.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
TxManager is AutoCloseable and releases what it was built on: JdbcTxManager its data
source when closeable, HibernateTxManager its session factory and then the data source
Hibernate was handed, which Hibernate itself never closes. DataExtension registers the
close as an onClose callback, so a stopped app no longer leaves its pool connected.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
flash-ext-vite runs Vite's dev server in DEV and otherwise serves the build from the
classpath, read straight from the directory or jar with no manifest. The Maven plugin
flash-ext-vite-maven-plugin builds the frontend at prepare-package and packages it
there, so mvn package makes a jar that serves its own frontend and mvn test needs no
Node. Three overrides remain (root, devPort, basePath); the package manager is read
from the nearest lockfile.
Serving fixes what the bundler got wrong: Vite's hashed files under assets/ are
cached as immutable instead of revalidated, HEAD reports the real Content-Length, a
missing asset is a 404 instead of the index, 304s carry ETag and Cache-Control, and
gzip respects q=0 and is prepared at boot. Every response header is pre-encoded, so
serving allocates nothing, which is what Response.type(byte[]) is for. Vite stops
with the app through onClose, and a lockfile change reinstalls before restarting.
The modes, strategies, logging and command-safety options, the asset-source
abstraction, the manifest and the Jackson dependency are gone: 1,535 lines of main
code become 480, plus 84 for the plugin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Maven plugin now writes a maximally compressed .gz beside every text file of 1 KB
and more, so the server compresses nothing and boot only reads the files: about 50 ms
for Glossa's 500. Hashed files under assets/ skip the ETag, which nothing ever asks for.
A path that is no file gets index.html only when the request's Accept names text/html,
as a browser navigation does. Everything else, an API call to a missing route included,
gets the app's own 404 instead of the index, and a dot in a client route no longer
matters. The base path itself always serves the app.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A path that is no file falls back to index.html when the request is a navigation:
Sec-Fetch-Mode: navigate, or an Accept naming text/html for older clients. That check,
Accept-Encoding and If-None-Match are all matched on the header bytes through the new
Request.headerView(name), so serving still allocates nothing. navigationOnly(false)
drops the check for an app that wants every GET miss to get the page.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
One release for both changes.
flash-ext-vite + flash-ext-vite-maven-plugin replace
flash-ext-web-bundler.new ViteExtension(): Vite's dev server in DEV; otherwise the build served from the classpath (flash-vite/, directory or jar, no manifest) as an SPA. Overrides:root,devPort,basePath,navigationOnly.buildgoal atprepare-package) installs, builds, packagesdist/and gzips text files at maximum compression, somvn packagemakes a jar that serves its own frontend andmvn testneeds no Node.assets/immutable, the rest revalidated by ETag, HEAD with the real length, 304 with its headers, gzip honouringq=0; a miss isindex.htmlonly for a browser navigation (Sec-Fetch-Mode: navigateorAccept: text/html), otherwise the app's 404. Headers pre-encoded and request headers read in place: nothing allocated per request.Response.type(byte[])andRequest.headerView(name).flash-extensions/flash-ext-vite/docs/README.md.flash-ext-data:
TxManagerisAutoCloseableandDataExtensioncloses it on stop, so a stopped app releases its connection pool (Hibernate's handed-in data source included).Tests: flash core 711, data-jdbc 19, data-hibernate 20, vite 14, plugin 2. Verified end to end on Glossa: plain
mvn package, thenjava -jaralone serves the SPA. Mixed routing checked by hand on FastPathRouter.🤖 Generated with Claude Code