Replace webpack and Module Federation with Vite 8. The controller build
emits one entry per shared module (lib, web_ui, typebox, antd, react,
react-dom, react-router) and lists them in manifest.json. The controller
turns that into an import map in index.html, and plugins are built as
ES modules that import the shared modules by name and are loaded with
import().
The shared Vite setup lives in @clusterio/web_ui/vite.mjs. Plugins use
clusterioPlugin(), which exposes index, package.json and web/index under
the same keys the webpack template used. The --dev and --dev-plugin
flags now run the Vite dev server in middleware mode with hot module
replacement.
Browser polyfills move from web_ui to lib, which is the code that needs
them, and lib sets the process and Buffer globals itself.
Refs #1127
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The drawer actions move to its header as Export, Import and a trash
icon for Delete. Import and Delete are disabled while an instance
holds the player, since the stored data is out of date until it
uploads. The drawer also shows color and cheat mode.
Inventory tables get title case names, pagination at 10 rows, item
search, sorting and quality icons. The player list shows force with
a filter instead of generation, and the database stats use
Descriptions without the largest entry.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Admins had no way to look at or fix the player data the controller
stores when a sync went wrong. The web page now lists every stored
entry with its generation, size and the instance holding the lock, and
opens a drawer per player with an inventory summary, JSON export and
import, delete and lock release. The same operations are exposed as
clusterioctl player-sync commands.
Import bumps the generation past the stored one so instances holding an
older copy download the new data on the next join. Import and delete
are refused while an instance holds the lock, since its upload on leave
would undo the change. A new player_sync.inventory.modify permission
gates the write operations.
Closes#1003
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The plugin syncs more than inventories now (settings, appearance, recipe
notifications), so name it for what it does. The package becomes
@clusterio/plugin-player_sync and every inventory_sync identifier follows.
A migration entrypoint renames the inventory_sync config fields, including
load_plugin, and the inventory view permission. The plugin moves
inventories.json in the database directory to player_sync.json and
storage.inventory_sync in saves to storage.player_sync itself, and closes
dialogs left open under the old GUI names on startup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>