Привет! Хочу описать ситуацию с моделями и динамическим спавном: хочется сделать это в ближайшее время. Мы в комитете эффектора рассмотрели ряд апи, все по своему интересны, но в целом не были учтены три главные проблемы, хочу их озвучить для вас, может вам придет что-то на ум)
Спавн моделей будет работать примерно как вызов fork для каждого инстанса. Тело фабрики при этом вызывается один раз, то есть юниты не пересоздаются, все как мы привыкли. Разница в том, что статические фабрики можно спавнить радикально эффективнее, разница как с первой версией fork с линейной сложностью и текущей которую в принципе малореально увидеть на мониторинге приложения.
Итак, проблемы которые нужно решить проектируя апи:
Как пробрасывать аргументы в фабрику, которая вызывается один раз?
Нужно так или иначе сделать все аргументы сторами и возникает вопрос как сделать это удобнее всего?
Можно сделать объект с дефолтными значениями, внутри колбэка они станут сторами:
const userModel = model({name: '', age: 18}, ({name, age}) => {
const $profile = combine({name, age})
return {$name: name, $age: age, $profile}
})
const alice = spawn(userModel, {name: 'alice '})
const bob = spawn(userModel, {name: 'bob ', age: 23})
Можно задавать то, что будет параметром изнутри колбэка, возвратом нужных сторов в отдельном поле params. Выглядит и ощущается как работа с prepend, если вы понимаете о чем я 😃 Поэтому рабочий вариант тот который описан выше
UPD 12.04.24: есть необходимость гарантировать, что апи будет расширяемым, поэтому предпочтительна объектная форма с отдельным полем для значений. Во время обсуждения в чате предлагалось название поля default, но что, если далее мы будем предлагать модели без опциональных полей, только с обязательными? В vue используется название props, можно использовать его:
const userModel = model({
props: {name: '', age: 18},
create({name, age}) {
const $profile = combine({name, age})
return {$name: name, $age: age, $profile}
}
})
const alice = spawn(userModel, {name: 'alice '})
const bob = spawn(userModel, {name: 'bob ', age: 23})
Как хранить инстансы модели? Модель можно спавнить в реакт компоненте, тогда инстанс хранится в компоненте и удаляется вместе с анмаунтом, удобно, но подходит не всегда, нам еще как-то надо будет это всё тестировать, не так ли 😃
Тут так или иначе все равно начинает всплывать keyval в той или иной форме, возможно он должен быть больше похож на entity adapter из rtk? Не понятно
Например, можно спавнить по одному инстансу на каждый итем в сторе-массиве примерно как это делает хук useList:
const $usersData = createStore([
{name: 'alice', age: 19},
{name: 'bob', age: 23},
])
const users = list($usersData, userModel)
В примере выше и далее используется модель из первого фрагмента кода
Тогда, keyval бы выглядел так:
const $usersData = createStore({
alice: {name: 'alice', age: 19},
bob: {name: 'bob', age: 23},
})
const users = keyval({
source: $usersData,
model: userModel,
})
const User = ({id}) => {
const {$profile: profileValue} = useModel(users, id)
return <div>{profileValue.age}</div>
}
Если вам в этот момент начинает казаться, что чего-то не хватает, то вы полностью правы 😃