Skip to content

Commit

Permalink
perf(core): memoize prepareFormState (#7498)
Browse files Browse the repository at this point in the history
* perf(core): memoize prepareFormState

* refactor(core): update root form state options

* fix(core): fix memoization bugs

* test(core): finish tests for every form option

* fix(core): fix stale `fieldGroupState` memo result

* refactor(core): return named function for readability

* docs(core): add JSDoc for `getId`

* refactor(core): mark sub-functions of `PrepareFormState` as internal

* fix: don't use symbols in weakmaps for firefox compat
  • Loading branch information
ricokahler committed Sep 17, 2024
1 parent 4a50023 commit 3bf7096
Show file tree
Hide file tree
Showing 19 changed files with 2,434 additions and 1,049 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ export function TestForm(props: TestFormProps) {
validateStaticDocument(document, workspace, (result) => setValidation(result))
}, [document, workspace])

const formState = useFormState(schemaType, {
const formState = useFormState({
schemaType,
focusPath,
collapsedPaths,
collapsedFieldSets,
Expand All @@ -166,7 +167,7 @@ export function TestForm(props: TestFormProps) {
openPath,
presence: presenceFromProps,
validation,
value: document,
documentValue: document,
})

const formStateRef = useRef(formState)
Expand Down
20 changes: 13 additions & 7 deletions packages/sanity/src/core/form/store/__tests__/collapsible.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {describe, expect, it, test} from '@jest/globals'
import {beforeEach, describe, expect, it, test} from '@jest/globals'
import {Schema} from '@sanity/schema'
import {type ObjectSchemaType, type Path} from '@sanity/types'

import {pathToString} from '../../../field'
import {prepareFormState} from '../formState'
import {createPrepareFormState, type PrepareFormState} from '../formState'
import {type FieldMember, type ObjectFormNode} from '../types'
import {isObjectFormNode} from '../types/asserters'
import {DEFAULT_PROPS} from './shared'
Expand Down Expand Up @@ -81,6 +81,12 @@ function getBookType(fieldOptions: {
}).get('book')
}

let prepareFormState!: PrepareFormState

beforeEach(() => {
prepareFormState = createPrepareFormState()
})

test("doesn't make primitive fields collapsed even if they are configured to be", () => {
// Note: the schema validation should possibly enforce this
// Note2: We might want to support making all kinds of fields collapsible, even primitive fields
Expand All @@ -93,7 +99,7 @@ test("doesn't make primitive fields collapsed even if they are configured to be"
const result = prepareFormState({
...DEFAULT_PROPS,
schemaType: bookType,
document: {_id: 'foo', _type: 'book'},
documentValue: {_id: 'foo', _type: 'book'},
})

expect(result).not.toBe(null)
Expand Down Expand Up @@ -121,7 +127,7 @@ describe('collapsible object fields', () => {
const result = prepareFormState({
...DEFAULT_PROPS,
schemaType: bookType,
document: {_id: 'foo', _type: 'book'},
documentValue: {_id: 'foo', _type: 'book'},
})

expect(result).not.toBe(null)
Expand All @@ -141,7 +147,7 @@ describe('collapsible object fields', () => {
const result = prepareFormState({
...DEFAULT_PROPS,
schemaType: bookType,
document: {_id: 'foo', _type: 'book'},
documentValue: {_id: 'foo', _type: 'book'},
})

expect(result).not.toBe(null)
Expand All @@ -160,7 +166,7 @@ describe('collapsible object fields', () => {
const result = prepareFormState({
...DEFAULT_PROPS,
schemaType: bookType,
document: {_id: 'foo', _type: 'book'},
value: {_id: 'foo', _type: 'book'},
})

expect(result).not.toBe(null)
Expand All @@ -184,7 +190,7 @@ describe('collapsible object fields', () => {
const result = prepareFormState({
...DEFAULT_PROPS,
schemaType: bookType,
document: {_id: 'foo', _type: 'book'},
documentValue: {_id: 'foo', _type: 'book'},
})

expect(result).not.toBe(null)
Expand Down
16 changes: 11 additions & 5 deletions packages/sanity/src/core/form/store/__tests__/equality.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {expect, test} from '@jest/globals'
import {beforeEach, expect, test} from '@jest/globals'
import {Schema} from '@sanity/schema'
import {type ConditionalProperty} from '@sanity/types'

import {prepareFormState} from '../formState'
import {createPrepareFormState, type PrepareFormState} from '../formState'
import {DEFAULT_PROPS} from './shared'

function getBookType(properties: {
Expand Down Expand Up @@ -73,20 +73,26 @@ function getBookType(properties: {
}).get('book')
}

let prepareFormState!: PrepareFormState

beforeEach(() => {
prepareFormState = createPrepareFormState()
})

test('it doesnt return new object equalities given the same input', () => {
const document = {_id: 'test', _type: 'foo'}
const documentValue = {_id: 'test', _type: 'foo'}
const bookType = getBookType({})

const state1 = prepareFormState({
...DEFAULT_PROPS,
schemaType: bookType,
document,
documentValue,
})

const state2 = prepareFormState({
...DEFAULT_PROPS,
schemaType: bookType,
document,
documentValue,
})
expect(state1).not.toBe(null)
expect(state2).not.toBe(null)
Expand Down
Loading

0 comments on commit 3bf7096

Please sign in to comment.