xaviergonz / mobx-keystone

A MobX powered state management solution based on data trees with first class support for Typescript, support for snapshots, patches and much more
https://mobx-keystone.js.org
MIT License
554 stars 25 forks source link

Supporting something like array.insert? #511

Closed PEZO19 closed 1 year ago

PEZO19 commented 1 year ago

Hi there! I am fairly new to MST/keystone and trying to wrap my head around the philosophy, features, implementation details.

I have found many issues around arrays/ordering in MST/keystone repos (adding-replacing gotchas, problems around safeReference, etc.), however I did not find something like .insert(index, newElementArray) as part of the API.

  1. Is there an approach/canonicial way to mimic .insert like behaviour? What are the gotchas?
  2. If there is no canonical way: why, what is the main issue?
  3. If there are only dirty workarounds: as far as I understand keystone handles references explicitly, so my question is if this information can be used to support something like .insert across the app state.

Eg.:

const array = [0,1,5,6]
array.insert(2, [2,3,4]) // +3 length
console.log(array) // [0,1,2,3,4,5,6]

**Patch/inverse patch info (merged to be more concise)

replace, 2, 5->2 replace, 3, 6->3 add, 4, 4 add, 5, 5 add, 6, 6

And I do not know about the implementation how references can / should work in all cases, but if an identity is resolved through an explicit ID/address, then this shift/insert does not seem to be an issue (for references pointing to indices after the added part), meanwhile, in case of path-based identity, we could just update the observers not to observe /2 /3 anymore, but /5 and /6 instead (just adding the same +3 everywhere). Maybe both are semantically valid insertion types, .insertKeepingPathRef vs .insertKeepingIdRef. Furthermore, if path based identity is lazily used/calculated, then there is no update/change needed for observers (of this array) at all.

Unfortunately, I am not familiar with array/model semantics of keystone, so I felt I had to raise this question, sorry if it misses some points.

xaviergonz commented 1 year ago

you may use the standard Javascript splice to do that insert

splice(2, 0, 2, 3, 4) would be the equivalent to your insert

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

PEZO19 commented 1 year ago

@xaviergonz Oh great, thanks. Somehow I though it is necessary to keep the same number of elements (deleted/replaced) in MST/keystone environment, I do not know why I had this assumption.