Add comments to cloneDeepSerializable()
https://github.com/theatre-js/theatre/pull/118#discussion_r846635429
This commit is contained in:
parent
679629def8
commit
a5cf72cd57
2 changed files with 18 additions and 5 deletions
|
@ -609,6 +609,11 @@ export interface IBasePropType<
|
||||||
* Each prop config has a `deserializeAndSanitize()` function that deserializes and sanitizes
|
* Each prop config has a `deserializeAndSanitize()` function that deserializes and sanitizes
|
||||||
* any js value into one that is acceptable by this prop config, or `undefined`.
|
* any js value into one that is acceptable by this prop config, or `undefined`.
|
||||||
*
|
*
|
||||||
|
* As a rule, the value returned by this function should not hold any reference to `json` or any
|
||||||
|
* other value referenced by the descendent props of `json`. This is to ensure that json values
|
||||||
|
* controlled by the user can never change the values in the store. See `deserializeAndSanitize()` in
|
||||||
|
* `t.compound()` or `t.rgba()` as examples.
|
||||||
|
*
|
||||||
* The `DeserializeType` is usually equal to `ValueType`. That is the case with
|
* The `DeserializeType` is usually equal to `ValueType`. That is the case with
|
||||||
* all simple prop configs, such as `number`, `string`, or `rgba`. However, composite
|
* all simple prop configs, such as `number`, `string`, or `rgba`. However, composite
|
||||||
* configs such as `compound` or `enum` may deserialize+sanitize into a partial value. For example,
|
* configs such as `compound` or `enum` may deserialize+sanitize into a partial value. For example,
|
||||||
|
|
|
@ -17,7 +17,15 @@ import {getPropConfigByPath} from '@theatre/shared/propTypes/utils'
|
||||||
import {isPlainObject} from 'lodash-es'
|
import {isPlainObject} from 'lodash-es'
|
||||||
import userReadableTypeOfValue from '@theatre/shared/utils/userReadableTypeOfValue'
|
import userReadableTypeOfValue from '@theatre/shared/utils/userReadableTypeOfValue'
|
||||||
|
|
||||||
function cloneDeepSerializable<T>(v: T): T | undefined {
|
/**
|
||||||
|
* Deep-clones a plain JS object or a `string | number | boolean`. In case of a plain
|
||||||
|
* object, all its sub-props that aren't `string | number | boolean` get pruned. Also,
|
||||||
|
* all empty objects (i.e. `{}`) get pruned.
|
||||||
|
*
|
||||||
|
* This is only used by {@link ITransactionPrivateApi.set} and it follows the global rule
|
||||||
|
* that values pointed to by `object.props[...]` are never `null | undefined` or an empty object.
|
||||||
|
*/
|
||||||
|
function cloneDeepSerializableAndPrune<T>(v: T): T | undefined {
|
||||||
if (
|
if (
|
||||||
typeof v === 'boolean' ||
|
typeof v === 'boolean' ||
|
||||||
typeof v === 'string' ||
|
typeof v === 'string' ||
|
||||||
|
@ -28,8 +36,8 @@ function cloneDeepSerializable<T>(v: T): T | undefined {
|
||||||
const cloned: $IntentionalAny = {}
|
const cloned: $IntentionalAny = {}
|
||||||
let clonedAtLeastOneProp = false
|
let clonedAtLeastOneProp = false
|
||||||
for (const [key, val] of Object.entries(v)) {
|
for (const [key, val] of Object.entries(v)) {
|
||||||
const clonedVal = cloneDeepSerializable(val)
|
const clonedVal = cloneDeepSerializableAndPrune(val)
|
||||||
if (typeof clonedVal !== 'undefined') {
|
if (clonedVal !== undefined) {
|
||||||
cloned[key] = val
|
cloned[key] = val
|
||||||
clonedAtLeastOneProp = true
|
clonedAtLeastOneProp = true
|
||||||
}
|
}
|
||||||
|
@ -69,7 +77,7 @@ export default function createTransactionPrivateApi(
|
||||||
return {
|
return {
|
||||||
set: (pointer, value) => {
|
set: (pointer, value) => {
|
||||||
ensureRunning()
|
ensureRunning()
|
||||||
const _value = cloneDeepSerializable(value)
|
const _value = cloneDeepSerializableAndPrune(value)
|
||||||
if (typeof _value === 'undefined') return
|
if (typeof _value === 'undefined') return
|
||||||
|
|
||||||
const {root, path} = getPointerParts(pointer as Pointer<$FixMe>)
|
const {root, path} = getPointerParts(pointer as Pointer<$FixMe>)
|
||||||
|
@ -104,7 +112,7 @@ export default function createTransactionPrivateApi(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const deserialized = cloneDeepSerializable(
|
const deserialized = cloneDeepSerializableAndPrune(
|
||||||
propConfig.deserializeAndSanitize(value),
|
propConfig.deserializeAndSanitize(value),
|
||||||
)
|
)
|
||||||
if (deserialized === undefined) {
|
if (deserialized === undefined) {
|
||||||
|
|
Loading…
Reference in a new issue