Миграция
InferDI документирует breaking changes по major versions. Источник истины остаётся в packages/inferdi/MIGRATION.md, а текущий путь миграции собран здесь.
Переход на 5.0
v5 - это релиз адаптеров. Основной пакет не менялся. Повышение версии нужно, чтобы все опубликованные пакеты остались в синхронных версиях, а адаптеры фреймворков использовали общий контракт очистки.
Общие контракты адаптеров:
createScope,setupScope,disposeScope,autoDisposeиonDisposeErrorиспользуют одинаковые термины.MaybePromise,InferdiScope,InferdiRootиInferdiScopeOfэкспортируются во всех адаптерах.- Если
setupScopeпадает, адаптер поднимает только исходную ошибку setup. - Ошибки очистки во время setup teardown идут в
onDisposeErrorили приёмник адаптера. - Упавший запрос очищает scope даже после
skipInferdiDispose, кроме документированного ограничения Express. - Cleanup hooks видят публичный слот scope, пока выполняются.
Заметки по адаптерам
| Пакет | Что изменилось |
|---|---|
@inferdi/fastify | logDisposeError переименован в onDisposeError; InferdiScope.dispose() может вернуть void или Promise<void>; добавлены disposeScope, autoDispose, skipInferdiDispose, InferdiScopeOf. |
@inferdi/hono | Ошибки очистки после next() логируются или идут в onDisposeError; они больше не заменяют успешный ответ. Setup teardown больше не бросает AggregateError. |
@inferdi/express | onDisposeError теперь per-error-приёмник для setup teardown и завершения response. Express не может принудительно очистить scope с пропущенной автоочисткой при обработанной ошибке маршрута. |
@inferdi/koa | Setup teardown поднимает только ошибку setup. Downstream-ошибка очищает scope даже после skipInferdiDispose(ctx). |
@inferdi/elysia | Setup teardown поднимает только ошибку setup. Ошибка очистки идёт в onDisposeError или console.error. |
Переход на 4.0
v4 ужесточает семантику времени жизни Lazy<T>. Managed lazy companion теперь сохраняет время жизни цели. Singleton может инжектить только Lazy<singleton>.
Главные изменения:
AllowedDeps<T, 'singleton'>больше не принимает произвольныйLazy<V>.LazySpec<V, TargetKind>стал публичным типом для явных форм контейнера и модуля.- Runtime-исключение для lazy применяется только когда target kind равен
singleton. - Singleton, который инжектил
Lazy<scoped>илиLazy<transient>, должен изменить время жизни цели или потребителя.
Типовые исправления:
// v3
.registerClass('req', RequestContext, [], 'scoped', 'reqLazy')
.registerClass('app', AppService, ['reqLazy'], 'singleton')
// v4: делаем потребителя scoped
.registerClass('req', RequestContext, [], 'scoped', 'reqLazy')
.registerClass('app', AppService, ['reqLazy'], 'scoped')// v3
type Deps = SpecMap<{ clock: Clock }> & {
clockLazy: Spec<Lazy<Clock>, 'transient'>
}
// v4
type Deps = SpecMap<{ clock: Clock }> & {
clockLazy: LazySpec<Clock, 'singleton'>
}Переход на 3.0
v3 переносит безопасность времени жизни в систему типов. Runtime behavior остаётся совместимым, а runtime-защита в strict mode остаётся вторым рубежом.
Главные изменения:
- Записи
DependenciesMapсталиSpec<V, Kind>вместо голых типов сервисов. RegistrationKind,Spec<V, K>иSpecMap<M, K>стали публичными экспортами.registerFactoryсужает параметрcдля singleton-фабрик.registerClassфильтруетdepsдля singleton-регистраций.override(key, value)сохраняет исходный вид времени жизни.new Container({ strict: false })может отключить runtime-проверки циклов и времени жизни после аудита графа.
Типовые исправления:
// v2
const c = new Container() as Container<{ a: A; b: B }>
// v3
const c = new Container() as Container<SpecMap<{ a: A; b: B }>>// v2
const mod: Module<{ cfg: Config }, { db: Db }> = (c) => ...
// v3
const mod: Module<
SpecMap<{ cfg: Config }>,
SpecMap<{ db: Db }>
> = (c) => ...Переход на 2.0
В v2 есть два механических breaking changes.
container.cradle удалён
Используйте .get(key):
// 1.x
const { db, logger } = container.cradle
// 2.x
const db = container.get('db')
const logger = container.get('logger')registerClass(..., lazy: true) стал lazyKey
Передавайте companion-ключ:
// 1.x
.registerClass('clock', Clock, [], 'transient', true)
// 2.x
.registerClass('clock', Clock, [], 'transient', 'clockLazy')v2 также добавил string- и symbol-ключи во все методы регистрации и уточнил диагностику очищенного предка.
Версии в lockstep
Все опубликованные пакеты InferDI имеют одну версию:
При обновлении адаптеров держите пакет адаптера и @inferdi/inferdi на совпадающих major-версиях.
Чеклист обновления
- Прочитать заметки о миграции для всех major-версий, через которые проходите.
- Обновить
@inferdi/inferdiи все установленные адаптеры вместе. - Запустить type tests или
tsc --noEmit, чтобы поймать изменения формы графа. - Запустить runtime tests в strict mode.
- Проверить владение scope запроса, если используются
skipInferdiDispose,autoDispose: falseили пользовательскийdisposeScope.
Стабильные границы
Основной пакет остаётся без декораторов и runtime-зависимостей. Поведение жизненного цикла фреймворков живёт в пакетах адаптеров, а не в @inferdi/inferdi.
