RDA map constrain
hediyi opened this issue · comments
Goal
Guarding state integrity from arbitrary actions. Known use cases:
- disable removal by action
- ensure presence of a key
Cover these cases first and add more constraints later.
API
constructor (keySchema, valueRDA, constrain?)
constrain {
set?:boolean | (k, v) => boolean
remove?:boolean | (k) => boolean
move?:boolean | (f, t) => boolean
}
Considerations
should we impose constraints exactly as specified?
An action may be replaced by a combination of other actions:
- set(k, v) = reset({..., k: v})
- remove(k) = reset({...}) (map without k)
- move(f, t) = set(t, V(f)) + remove(f)
Probably should keep it simple. These are not technically equivalent though, maybe overthinking.
should we impose constraints in action() or apply()?
Imposing constraints in action() seems easier to do, but apply() may be the way to go because action objects may not be constructed by action(). Experiment with and test both.
if we impose constraints in apply(), will the inverses be valid?
Test the following cases,
- upsert
- if element present, inverse upsert
- not present, inverse setDeleted
- setDeleted, inverse setDeleted
- move, inverse move
probably should return false from apply() if action is not allowed
User may use return to decide whether to sync with other stores.
API update
constructor (keySchema, valueRDA, constrain?)
constrain {
set?:boolean | (k, v) => boolean
remove?:boolean | (k) => boolean
move?:boolean | (f, t) => boolean
maxKeyLength?:number
}