From 3f5b9027396c1c0542cea4eb65610dd13b5ffe6d Mon Sep 17 00:00:00 2001 From: Aria Minaei Date: Thu, 24 Nov 2022 13:36:52 +0100 Subject: [PATCH] Document `minimalOverride()` --- theatre/shared/src/utils/minimalOverride.ts | 39 +++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/theatre/shared/src/utils/minimalOverride.ts b/theatre/shared/src/utils/minimalOverride.ts index 7d192b2..758d746 100644 --- a/theatre/shared/src/utils/minimalOverride.ts +++ b/theatre/shared/src/utils/minimalOverride.ts @@ -21,6 +21,45 @@ function typeOfValue(v: unknown): ValueType { } } +/** + * Returns an object that deep-equals `override`, but uses as much of the references from `base` as possible. + * + * It's better to explain this with a few examples: + * ```ts + * const base = {a: {a1: 1}, b: 1} + * const override = {a: {a1: 1}, b: 2} // notice how the value of b is different, but a deep-equals the value of a in base + * const result = minimalOverride(base, override) + * console.log(result === base) // false + * console.log(result === override) // false + * console.log(result.a === base.a) // true (base.a was re-used, because it deep-equals override.a) + * + * // Another example: + * const base = {a: {a1: 1}, b: 1} + * const override = {a: {a1: 2}, b: 1} // notice how the value of a does not deep-equal the value of a in base + * const result = minimalOverride(base, override) + * console.log(result === base) // false + * console.log(result === override) // false + * console.log(result.a === base.a) // false + * console.log(result.a === override.a) // true (override.a is used here, because it does not deep-equal base.a) + * ``` + * + * @remarks + * We don't use this function anymore, but we're keeping it around as it's likely to be used again in the future. + * + * The way it used to be used, was in `transactionApi.set()`. Consider the following example: + * ```ts + * studio.transaction(({set}) => { + * set(light.props, {position: {x: 1, y: 2}, intensity: 1}) + * }) + * + * studio.transaction(({set}) => { + * // Notice that props.position is the same as before. We just want to change the intensity in this transaction. + * // So what will actually happen is that props.position will be re-used and untouched (and won't end up in the transaction record), + * // and this transaction will only touch the value for props.intensity. + * set(light.props, {position: {x: 1, y: 2}, intensity: 2}) + * }) + * ``` + */ export default function minimalOverride(base: T, override: T): T { const typeofOverride = typeOfValue(override) if (typeofOverride === ValueType.Opaque) {