Files
XC_VM/docs/ru/development/module-lifecycle.md
T
Divarion_D d4da90f37b fix(docs): translate bold spans atomically and auto-prune orphaned ru pages
The line-by-line web translator reordered words inside `**bold**` spans and
misplaced/dropped the markers, producing `**LB` or `****` (empty bold). Mask
each `**...**` as ONE atomic sentinel: translate the inner text on its own,
then store the whole balanced `**inner**` — the engine never sees the markers
and cannot reorder or collapse them. Also harden the anthropic prompt to keep
emphasis balanced.

Auto-prune: after translating, delete generated docs/ru files whose docs/en
source no longer exists (renamed/removed) and drop now-empty dirs, so the tree
mirrors docs/en 1:1 (removes the stale development/modules.md and
guides/geoip-and-device-detection.md).

Bump PROMPT_VERSION to 6 to invalidate the contaminated cache and regenerate
docs/ru (0 broken bold spans remaining, aside from pre-existing multi-line
bold that spans a soft line break).
2026-08-27 18:07:43 +03:00

142 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Жизненный цикл модуля
Как XC_VM обнаруживает, загружает, включает/отключает, устанавливает и распространяет модули во время выполнения. Чтобы создать модуль, смотрите [Разработка модуля](module-authoring.md); для его расширений смотрите [Точки расширения модуля](module-extension-points.md).
## Включение / выключение модулей
Все обнаруженные модули загружаются по умолчанию. Используйте `src/config/modules.php` для переопределения состояния:
```php
return [
'my-module' => ['state' => 'disabled'], // preferred
// or legacy boolean (still accepted):
'my-module' => ['enabled' => false],
];
```
Доступные значения `state` (подкрепленные перечислением `ModuleState`):
|Ценность|Значение|
| ----- | ------- |
| `enabled` |Загрузка модуля (по умолчанию)|
| `disabled` |Модуль обнаружен, но пропущен|
| `installing` |Переходное состояние, заданное значением `ModuleManager` во время установки|
| `failed` |Ошибка установки; модуль пропущен (не загружен)|
> **Панельная диагностика.** На странице **Модули** отображается желтый значок **⚠ Проблема зависимости** рядом со статусом модуля, если требуемая зависимость отсутствует или не включена (например, в `plex` указано `Enabled`, а в `watch` - `failed`). Во всплывающей подсказке к значку перечислены конкретные проблемы. Это поле `dependency_warnings` вычисляется с помощью `ModuleManager::listModules()`.
Чтобы переопределить класс, разрешенный для модуля:
```php
return [
'my-module' => ['class' => 'XcVm\\Module\\MyModuleV2\\MyModuleV2Module'],
];
```
`config/modules.php` содержит только переопределения. Пустой или отсутствующий файл означает, что все обнаруженные
загружаются модули.
---
## Как работает загрузка
`ModuleLoader` выполняет эти действия при каждом запросе:
1. Сканирование `src/Modules/*/module.json`
2. Применяет переопределения из `config/modules.php`
3. Фильтры по окружающей среде (`main` / `lb` / `any`)
4. Определяет порядок загрузки:
- `pruneUnsatisfiableModules()` удаляет модули, требуемые зависимости которых недоступны (каскадно, с зарегистрированным предупреждением), чтобы загрузка никогда не прерывалась
- Топологическая сортировка (DFS) по графу зависимостей
- В пределах одной и той же группы зависимостей выполните сортировку по убыванию `priority`, затем по алфавиту
- Выдает `ModuleCycleException` для циклов (подкласс `\RuntimeException`; циклические зависимости остаются фатальными)
- Отсутствующие необязательные зависимости автоматически пропускаются
5. Resolves class name: `my-module` → FQN `XcVm\Module\MyModule\MyModuleModule`
(kebab-case → PascalCase; может быть переопределен с помощью клавиши `class` в конфигурации)
6. Регистрирует автозагрузчик модуля PSR-4 (сопоставляет `XcVm\Module\<Name>` с каталогом модуля)
7. Создает экземпляр класса module
В веб-контексте:
- `bootAll($container, $router)` → вызовы `boot()`, `registerRoutes()`, `registerNavbar()`,
и подписывается на события для каждого загруженного модуля
В контексте командной строки:
- `registerAllCommands($registry)` → вызывает `registerCommands()` для каждого загруженного модуля
---
## Marketplace: установка через расширение C
Модули с платформы устанавливаются через `ModuleManager::downloadFromPlatform()`:
```php
$manager->downloadFromPlatform(slug: 'my-module', version: '1.2.0', apiKey: $key);
```
Под капотом:
1. `XC_VM::module_install($slug, $version, $apiKey)` — Расширение C загружает, расшифровывает и распаковывает файлы
2. `installModule($slug)` — запускает `install()` в модуле
3. `EventDispatcher::dispatch(new PackageInstalledEvent(...))` — отправляет событие
4. `hotReload($slug, $path)` — загружает модуль в текущем запросе **без перезапуска PHP-FPM**
---
## Изолированные подсистемы
Модуль может быть полностью изолированной подсистемой со своей собственной точкой входа и начальной загрузкой
(например, Ministra). Это **соглашение**, а не маркерный интерфейс — он остается
обычный модуль `ModuleInterface`/`BaseModule`:
```php
class MyModule extends BaseModule {
public function getName(): string {
return 'my-module';
}
public function getVersion(): string {
return '1.0.0';
}
}
```
Изоляция означает, что подсистема работает через свою собственную общедоступную точку входа (например,
`my-module/portal.php`, путь относительно `src/`, который обрабатывает свой собственный bootstrap)
с отдельным путем начальной загрузки. Он использует общую инфраструктуру (базу данных, кэш, конфигурацию), но
участвует ли **нет** в основных `Router`, `ModuleLoader::bootAll()` или
`NavbarRegistry`. Реализации `boot()` и `registerRoutes()` обычно являются
оставлено как унаследованное бездействие.
---
## Composer обнаружение пакета
Модули могут распространяться в виде Composer пакетов с `"type": "xcvm-module"`:
```json
{
"name": "vendor/my-xcvm-module",
"type": "xcvm-module",
"extra": {
"xcvm": {
"module-path": "src"
}
}
}
```
`ModuleLoader` автоматически сканирует `vendor/composer/installed.json` (Composer 1 и 2
форматирует) и обнаруживает все установленные пакеты `xcvm-module` вместе со встроенным
каталог `src/Modules/`. Пакеты дедуплицируются — модуль как в `modules/`, так и в
`vendor/` загружается только один раз.
---