Привет! Хочу описать ситуацию с моделями и динамическим спавном: хочется сделать это в ближайшее время. Мы в комитете эффектора рассмотрели ряд апи, все по своему интересны, но в целом не были учтены три главные проблемы, хочу их озвучить для вас, может вам придет что-то на ум)

Спавн моделей будет работать примерно как вызов 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>
}

Если вам в этот момент начинает казаться, что чего-то не хватает, то вы полностью правы 😃