From b2116e9a5d655ee35e438333843030b77d6f9ceb Mon Sep 17 00:00:00 2001 From: Aria Minaei Date: Thu, 1 Dec 2022 14:59:03 +0100 Subject: [PATCH] Unify Derivation and Prism 11/n `useDerivation()` => `usePrismInstance()` --- packages/dataverse/src/PointerProxy.ts | 2 +- packages/dataverse/src/pointer.ts | 2 +- .../src/prisms/iterateAndCountTicks.ts | 12 +++---- packages/dataverse/src/prisms/iterateOver.ts | 12 +++---- .../dataverse/src/prisms/prism/prism.test.ts | 16 ++++----- packages/dataverse/src/prisms/prism/prism.ts | 12 +++---- packages/react/src/index.ts | 34 +++++++++---------- .../useEditingToolsForSimpleProp.tsx | 4 +-- .../studio/src/uiComponents/usePresence.tsx | 4 +-- theatre/studio/src/utils/derive-utils.tsx | 4 +-- 10 files changed, 51 insertions(+), 51 deletions(-) diff --git a/packages/dataverse/src/PointerProxy.ts b/packages/dataverse/src/PointerProxy.ts index 7ac2d7e..906045d 100644 --- a/packages/dataverse/src/PointerProxy.ts +++ b/packages/dataverse/src/PointerProxy.ts @@ -8,7 +8,7 @@ import type {$FixMe, $IntentionalAny} from './types' import prism from './prisms/prism/prism' /** - * Allows creating pointer-derivations where the pointer can be switched out. + * Allows creating pointer-prisms where the pointer can be switched out. * * @remarks * This allows reacting not just to value changes at a certain pointer, but changes diff --git a/packages/dataverse/src/pointer.ts b/packages/dataverse/src/pointer.ts index 3301126..ae1c25c 100644 --- a/packages/dataverse/src/pointer.ts +++ b/packages/dataverse/src/pointer.ts @@ -144,7 +144,7 @@ export const getPointerParts = <_>( * Creates a pointer to a (nested) property of an {@link Atom}. * * @remarks - * Pointers are used to make derivations of properties or nested properties of + * Pointers are used to make prisms of properties or nested properties of * {@link Atom|Atoms}. * * Pointers also allow easy construction of new pointers pointing to nested members diff --git a/packages/dataverse/src/prisms/iterateAndCountTicks.ts b/packages/dataverse/src/prisms/iterateAndCountTicks.ts index a41e168..cecc3a3 100644 --- a/packages/dataverse/src/prisms/iterateAndCountTicks.ts +++ b/packages/dataverse/src/prisms/iterateAndCountTicks.ts @@ -5,15 +5,15 @@ import type {Prism} from './Interface' import {isPrism} from './Interface' export default function* iterateAndCountTicks( - pointerOrDerivation: Prism | Pointer, + pointerOrPrism: Prism | Pointer, ): Generator<{value: V; ticks: number}, void, void> { let d - if (isPointer(pointerOrDerivation)) { - d = pointerToPrism(pointerOrDerivation) as Prism - } else if (isPrism(pointerOrDerivation)) { - d = pointerOrDerivation + if (isPointer(pointerOrPrism)) { + d = pointerToPrism(pointerOrPrism) as Prism + } else if (isPrism(pointerOrPrism)) { + d = pointerOrPrism } else { - throw new Error(`Only pointers and derivations are supported`) + throw new Error(`Only pointers and prisms are supported`) } let ticksCountedSinceLastYield = 0 diff --git a/packages/dataverse/src/prisms/iterateOver.ts b/packages/dataverse/src/prisms/iterateOver.ts index 59d4861..93cf066 100644 --- a/packages/dataverse/src/prisms/iterateOver.ts +++ b/packages/dataverse/src/prisms/iterateOver.ts @@ -6,15 +6,15 @@ import type {Prism} from './Interface' import {isPrism} from './Interface' export default function* iterateOver( - pointerOrDerivation: Prism | Pointer, + pointerOrPrism: Prism | Pointer, ): Generator { let d - if (isPointer(pointerOrDerivation)) { - d = pointerToPrism(pointerOrDerivation) as Prism - } else if (isPrism(pointerOrDerivation)) { - d = pointerOrDerivation + if (isPointer(pointerOrPrism)) { + d = pointerToPrism(pointerOrPrism) as Prism + } else if (isPrism(pointerOrPrism)) { + d = pointerOrPrism } else { - throw new Error(`Only pointers and derivations are supported`) + throw new Error(`Only pointers and prisms are supported`) } const ticker = new Ticker() diff --git a/packages/dataverse/src/prisms/prism/prism.test.ts b/packages/dataverse/src/prisms/prism/prism.test.ts index f318526..3d2ffa8 100644 --- a/packages/dataverse/src/prisms/prism/prism.test.ts +++ b/packages/dataverse/src/prisms/prism/prism.test.ts @@ -96,7 +96,7 @@ describe('prism', () => { const prsm = prism(() => { const n = val(a.pointer.letter) const iterationAtTimeOfCall = iteration - sequence.push({derivationCall: iterationAtTimeOfCall}) + sequence.push({prismCall: iterationAtTimeOfCall}) prism.effect( 'f', @@ -116,13 +116,13 @@ describe('prism', () => { sequence.push({change}) }) - expect(sequence).toMatchObject([{derivationCall: 0}, {effectCall: 0}]) + expect(sequence).toMatchObject([{prismCall: 0}, {effectCall: 0}]) sequence.length = 0 iteration++ a.setIn(['letter'], 'b') ticker.tick() - expect(sequence).toMatchObject([{derivationCall: 1}, {change: 'b'}]) + expect(sequence).toMatchObject([{prismCall: 1}, {change: 'b'}]) sequence.length = 0 deps = [1] @@ -130,7 +130,7 @@ describe('prism', () => { a.setIn(['letter'], 'c') ticker.tick() expect(sequence).toMatchObject([ - {derivationCall: 2}, + {prismCall: 2}, {cleanupCall: 0}, {effectCall: 2}, {change: 'c'}, @@ -156,7 +156,7 @@ describe('prism', () => { const prsm = prism(() => { const n = val(a.pointer.letter) const iterationAtTimeOfCall = iteration - sequence.push({derivationCall: iterationAtTimeOfCall}) + sequence.push({prismCall: iterationAtTimeOfCall}) const resultOfMemo = prism.memo( 'memo', @@ -177,7 +177,7 @@ describe('prism', () => { }) expect(sequence).toMatchObject([ - {derivationCall: 0}, + {prismCall: 0}, {memoCall: 0}, {resultOfMemo: 0}, ]) @@ -187,7 +187,7 @@ describe('prism', () => { a.setIn(['letter'], 'b') ticker.tick() expect(sequence).toMatchObject([ - {derivationCall: 1}, + {prismCall: 1}, {resultOfMemo: 0}, {change: 'b'}, ]) @@ -198,7 +198,7 @@ describe('prism', () => { a.setIn(['letter'], 'c') ticker.tick() expect(sequence).toMatchObject([ - {derivationCall: 2}, + {prismCall: 2}, {memoCall: 2}, {resultOfMemo: 2}, {change: 'c'}, diff --git a/packages/dataverse/src/prisms/prism/prism.ts b/packages/dataverse/src/prisms/prism/prism.ts index 1acb25d..8d9cb3b 100644 --- a/packages/dataverse/src/prisms/prism/prism.ts +++ b/packages/dataverse/src/prisms/prism/prism.ts @@ -51,7 +51,7 @@ class HotHandle { constructor( private readonly _fn: () => V, - private readonly _prismInstance: PrismDerivation, + private readonly _prismInstance: PrismInstance, ) { for (const d of this._dependencies) { d._addDependent(this._reactToDependencyGoingStale) @@ -198,7 +198,7 @@ class HotHandle { const emptyObject = {} -class PrismDerivation implements Prism { +class PrismInstance implements Prism { /** * Whether the object is a prism. */ @@ -336,8 +336,8 @@ class PrismDerivation implements Prism { * Design constraints: * - This fix should not have a perf-penalty in production. Perhaps use a global flag + `process.env.NODE_ENV !== 'production'` * to enable it. - * - In the case of `DerivationValuelessEmitter`, we don't control when the user calls - * `getValue()` (as opposed to `DerivationEmitter` which calls `getValue()` directly). + * - In the case of `onStale()`, we don't control when the user calls + * `getValue()` (as opposed to `onChange()` which calls `getValue()` directly). * Perhaps we can disable the check in that case. * - Probably the best place to add this check is right here in this method plus some changes to `reportResulutionStart()`, * which would have to be changed to let the caller know if there is an actual collector (a prism) @@ -700,7 +700,7 @@ function inPrism(): boolean { return !!hookScopeStack.peek() } -const possibleDerivationToValue =

| unknown>( +const possiblePrismToValue =

| unknown>( input: P, ): P extends Prism ? T : P => { if (isPrism(input)) { @@ -742,7 +742,7 @@ type IPrismFn = { * @param fn - The function to rerun when the prisms referenced in it change. */ const prism: IPrismFn = (fn) => { - return new PrismDerivation(fn) + return new PrismInstance(fn) } class ColdScope implements PrismScope { diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index ba94e5f..3df7246 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -65,7 +65,7 @@ export function usePrism( boxRef.current.set(fnAsCallback) } - const pr = useMemo( + const prsm = useMemo( () => prism(() => { const fn = boxRef.current.prism.getValue() @@ -74,7 +74,7 @@ export function usePrism( [], ) - return useDerivation(pr, debugLabel) + return usePrismInstance(prsm, debugLabel) } export const useVal: typeof val = (p: $IntentionalAny, debugLabel?: string) => { @@ -107,7 +107,7 @@ type QueueItem = { */ debug?: { /** - * The `debugLabel` given to `usePrism()/useDerivation()` + * The `debugLabel` given to `usePrism()/usePrismInstance()` */ label?: string /** @@ -115,8 +115,8 @@ type QueueItem = { */ traceOfFirstTimeRender: Error /** - * An array of the operations done on/about this useDerivation. This is helpful to trace - * why a useDerivation's update was added to the queue and why it re-rendered + * An array of the operations done on/about this usePrismInstance. This is helpful to trace + * why a usePrismInstance's update was added to the queue and why it re-rendered */ history: Array< /** @@ -150,11 +150,11 @@ type QueueItem = { */ lastValue: T /** - * Would be set to true if the element hosting the `useDerivation()` was unmounted + * Would be set to true if the element hosting the `usePrismInstance()` was unmounted */ unmounted: boolean /** - * Adds the `useDerivation` to the update queue + * Adds the `usePrismInstance` to the update queue */ queueUpdate: () => void /** @@ -224,7 +224,7 @@ function queueIfNeeded() { item.debug?.history.push(`queue: der.getValue() errored`) } console.error( - 'A `der.getValue()` in `useDerivation(der)` threw an error. ' + + 'A `der.getValue()` in `usePrismInstance(der)` threw an error. ' + "This may be a zombie child issue, so we're gonna try to get its value again in a normal react render phase." + 'If you see the same error again, then you either have an error in your prism code, or the deps array in `usePrism(fn, deps)` is missing ' + 'a dependency and causing the prism to read stale values.', @@ -268,19 +268,19 @@ function queueIfNeeded() { * * # Remove cold prism reads * - * Prior to the latest change, the first render of every `useDerivation()` resulted in a cold read of its inner prism. + * Prior to the latest change, the first render of every `usePrismInstance()` resulted in a cold read of its inner prism. * Cold reads are predictably slow. The reason we'd run cold reads was to comply with react's rule of not running side-effects * during render. (Turning a prism hot is _technically_ a side-effect). * * However, now that users are animating scenes with hundreds of objects in the same sequence, the lag started to be noticable. * - * This commit changes `useDerivation()` so that it turns its prism hot before rendering them. + * This commit changes `usePrismInstance()` so that it turns its prism hot before rendering them. * * # Freshen prisms before render * * Previously in order to avoid the zombie child problem (https://kaihao.dev/posts/stale-props-and-zombie-children-in-redux) * we deferred freshening the prisms to the render phase of components. This meant that if a prism's dependencies - * changed, `useDerivation()` would schedule a re-render, regardless of whether that change actually affected the prism's + * changed, `usePrismInstance()` would schedule a re-render, regardless of whether that change actually affected the prism's * value. Here is a contrived example: * * ```ts @@ -288,7 +288,7 @@ function queueIfNeeded() { * const isPositiveD = prism(() => num.prism.getValue() >= 0) * * const Comp = () => { - * return

{useDerivation(isPositiveD)}
+ * return
{usePrismInstance(isPositiveD)}
* } * * num.set(2) // would cause Comp to re-render- even though 1 is still a positive number @@ -301,9 +301,9 @@ function queueIfNeeded() { * the mounting tree. * * On the off-chance that one of them still turns out to be a zombile child, `runQueue` will defer that particular - * `useDerivation()` to be read inside a normal react render phase. + * `usePrismInstance()` to be read inside a normal react render phase. */ -export function useDerivation(der: Prism, debugLabel?: string): T { +export function usePrismInstance(der: Prism, debugLabel?: string): T { const _forceUpdate = useForceUpdate(debugLabel) const ref = useRef>(undefined as $IntentionalAny) @@ -347,7 +347,7 @@ export function useDerivation(der: Prism, debugLabel?: string): T { if (process.env.NODE_ENV !== 'production') { if (der !== ref.current.der) { console.error( - 'Argument `der` in `useDerivation(der)` should not change between renders.', + 'Argument `der` in `usePrismInstance(der)` should not change between renders.', ) } } @@ -389,7 +389,7 @@ export function usePrismWithoutReRender( ): Prism { const pr = useMemo(() => prism(fn), deps) - return useDerivationWithoutReRender(pr) + return usePrismInstanceWithoutReRender(pr) } /** @@ -398,7 +398,7 @@ export function usePrismWithoutReRender( * return the value of the prism, and it does not * re-render the component if the value of the prism changes. */ -export function useDerivationWithoutReRender(der: Prism): Prism { +export function usePrismInstanceWithoutReRender(der: Prism): Prism { useEffect(() => { const untap = der.keepHot() diff --git a/theatre/studio/src/propEditors/useEditingToolsForSimpleProp.tsx b/theatre/studio/src/propEditors/useEditingToolsForSimpleProp.tsx index 153104f..5882278 100644 --- a/theatre/studio/src/propEditors/useEditingToolsForSimpleProp.tsx +++ b/theatre/studio/src/propEditors/useEditingToolsForSimpleProp.tsx @@ -7,7 +7,7 @@ import getStudio from '@theatre/studio/getStudio' import type Scrub from '@theatre/studio/Scrub' import type {IContextMenuItem} from '@theatre/studio/uiComponents/simpleContextMenu/useContextMenu' import getDeep from '@theatre/shared/utils/getDeep' -import {useDerivation} from '@theatre/react' +import {usePrismInstance} from '@theatre/react' import type { $IntentionalAny, SerializablePrimitive as SerializablePrimitive, @@ -355,7 +355,7 @@ export function useEditingToolsForSimplePropInDetailsPanel< propConfig: PropTypeConfig_AllSimples, ): EditingTools { const der = getDerivation(pointerToProp, obj, propConfig) - return useDerivation(der) + return usePrismInstance(der) } type Shade = diff --git a/theatre/studio/src/uiComponents/usePresence.tsx b/theatre/studio/src/uiComponents/usePresence.tsx index 667e4f2..90d8c67 100644 --- a/theatre/studio/src/uiComponents/usePresence.tsx +++ b/theatre/studio/src/uiComponents/usePresence.tsx @@ -5,7 +5,7 @@ import {useEffect} from 'react' import {useLogger} from './useLogger' import {Box, prism, pointerToPrism} from '@theatre/dataverse' import {Atom} from '@theatre/dataverse' -import {useDerivation} from '@theatre/react' +import {usePrismInstance} from '@theatre/react' import {selectClosestHTMLAncestor} from '@theatre/studio/utils/selectClosestHTMLAncestor' /** To mean the presence value */ @@ -95,7 +95,7 @@ function createPresenceContext(options: { } }) }, [itemKey]) - return useDerivation(focusD) + return usePrismInstance(focusD) }, setUserHover(itemKeyOpt) { const prev = currentUserHoverItemB.get() diff --git a/theatre/studio/src/utils/derive-utils.tsx b/theatre/studio/src/utils/derive-utils.tsx index 9c363ab..f185f8a 100644 --- a/theatre/studio/src/utils/derive-utils.tsx +++ b/theatre/studio/src/utils/derive-utils.tsx @@ -1,6 +1,6 @@ import {isPrism, prism, val} from '@theatre/dataverse' import type {Prism, Pointer} from '@theatre/dataverse' -import {useDerivation} from '@theatre/react' +import {usePrismInstance} from '@theatre/react' import type {$IntentionalAny} from '@theatre/shared/utils/types' import React, {useMemo, useRef} from 'react' import {invariant} from './invariant' @@ -86,7 +86,7 @@ export function deriver( ) const allD = useMemo(() => deriveAllD(observables), observableArr) - const observedPropState = useDerivation(allD) + const observedPropState = usePrismInstance(allD) return ( observedPropState &&