Skip to content

Commit 9323314

Browse files
committed
docs: describe the migrated architecture
1 parent d9ee865 commit 9323314

1 file changed

Lines changed: 47 additions & 17 deletions

File tree

README.md

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,35 +26,62 @@ The plugin is the source of truth. Menu files stay under `plugins/BlueMenu/menus
2626

2727
## How a session works
2828

29-
1. A player runs `/bm editor` in game. The plugin opens a session against `wss://menu.blueva.net/ws` and hands the player a link.
30-
2. Opening the link binds that browser window to the session. Each window carries its own verification id, so a leaked link does not grant access on its own.
31-
3. If `require-confirmation` is on in `settings.yml`, the plugin waits for `/bm confirm` in game before the session becomes editable.
32-
4. The editor requests the menu list, loads a menu, and saves changes back through the same socket. With `auto-save` and `auto-reload` enabled, the plugin writes the YAML and reloads the menu immediately.
29+
1. A player runs `/bm editor` in game. The plugin asks the editor to open a session and hands the player a link.
30+
2. Opening the link registers that browser window and gives it its own verification id, so a leaked link does not grant access on its own.
31+
3. If `require-confirmation` is on in `settings.yml`, the plugin waits for `/bm confirm <id>` in game before the session becomes editable.
32+
4. From then on the browser edits over plain HTTP. Every operation that needs the server is forwarded to the plugin and answered by it.
3333

34-
Sessions expire on their own, and the plugin rejects any message whose session is unknown, consumed or unconfirmed.
34+
Sessions expire on their own, and the editor rejects any request whose session is unknown, consumed or unconfirmed.
35+
36+
## How the plugin is reached
37+
38+
The plugin is not a client the editor can call directly, so requests travel to it over a broadcast channel and come back over HTTP:
39+
40+
- The server registers once and stores its credentials in `webeditor-credentials.yml`.
41+
- It subscribes to its own private Reverb channel and keeps itself marked as reachable with a heartbeat.
42+
- A browser request that needs the server publishes an RPC request on that channel and waits; the plugin performs the operation and posts the answer back to `/api/plugin/rpc-response`.
43+
44+
That wait happens **inside** the browser's request while the answer arrives on a **different** request, so the web process must serve more than one request at a time. With a single worker the waiting request starves the one that would release it:
45+
46+
```bash
47+
PHP_CLI_SERVER_WORKERS=6 php artisan serve --host=0.0.0.0 --port=8000 --no-reload
48+
```
49+
50+
`artisan serve` only honours `PHP_CLI_SERVER_WORKERS` together with `--no-reload`.
51+
52+
## Demo mode
53+
54+
Opening the site without a session shows the editor running on the example menus the plugin ships. Everything renders and every editor works; only saving is unavailable, because there is no server behind it.
3555

3656
## Stack
3757

38-
- Laravel 13 on PHP 8.3+
58+
- Laravel 13 on PHP 8.3+, with Laravel Reverb for the channel the plugin listens on
3959
- React 19 with TypeScript 7, mounted from a Blade shell
60+
- CodeMirror 6 for the YAML editor, `yaml` for the document model
4061
- Vite 8 with the Laravel plugin, Tailwind 4 and Bunny Fonts
4162
- SQLite by default, MySQL in production
42-
- PHPUnit for tests
63+
- PHPUnit for the backend, Vitest for the editor
4364

4465
## Project Layout
4566

4667
```
4768
app/
48-
├── Http/Controllers/ HTTP entry points
49-
├── Models/ Eloquent models
50-
└── Providers/ service providers
69+
├── Enums/ domain vocabularies
70+
├── Events/ broadcast events, including the plugin RPC request
71+
├── Http/Controllers/Api/ browser endpoints
72+
├── Http/Controllers/Api/Plugin/ endpoints the plugin calls
73+
├── Models/ servers, sessions, verifications, settings
74+
└── Services/ session lifecycle, RPC bridge, maintenance, admin console
5175
resources/
52-
├── css/app.css Tailwind entry
53-
├── js/ React application, entry at app.tsx
54-
└── views/ Blade shell that mounts React
55-
routes/web.php web routes
56-
database/migrations/ schema
57-
tests/ PHPUnit feature and unit tests
76+
├── demo/ the sample menus the plugin ships
77+
├── js/editor/ menu model, yaml codec, validator, materials
78+
├── js/components/ editor chassis
79+
├── js/components/visual/ canvas, item editor, form builder, animator
80+
└── views/ Blade shells that mount React
81+
routes/web.php browser routes
82+
routes/plugin.php plugin routes
83+
routes/channels.php private channel authorisation
84+
public/editor/items/ item sprites, one folder per Minecraft version
5885
```
5986

6087
## Requirements
@@ -65,6 +92,7 @@ tests/ PHPUnit feature and unit tests
6592
| Composer | 2+ |
6693
| Node | 20+ |
6794
| Database | SQLite for local work, MySQL 8+ in production |
95+
| Reverb | Started with `php artisan reverb:start` |
6896

6997
## Getting Started
7098

@@ -96,15 +124,17 @@ composer dev
96124
```bash
97125
npm run dev # Vite dev server with hot reload
98126
npm run typecheck # tsc --noEmit
127+
npm test # Vitest, covering the yaml codec and the editor logic
99128
npm run build # production assets
100129
composer test # clears config, then runs PHPUnit
130+
php artisan reverb:start
101131
```
102132

103133
Run the narrowest test set that covers a change, for example `php artisan test --compact --filter=SomeTest`.
104134

105135
## Deployment
106136

107-
`.github/workflows/deploy.yml` typechecks, builds and runs the test suite on every push and pull request. On `main` it then pulls, installs production dependencies, rebuilds the assets, migrates and warms the caches on the host.
137+
`.github/workflows/deploy.yml` typechecks, builds and runs both test suites on every push and pull request. On `main` it then pulls, installs production dependencies, rebuilds the assets, migrates and warms the caches on the host.
108138

109139
## Authors
110140

0 commit comments

Comments
 (0)