-
Notifications
You must be signed in to change notification settings - Fork 450
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Document Provider #4938
base: next
Are you sure you want to change the base?
[WIP] Document Provider #4938
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Ignored Deployment
|
fd97814
to
f0dcfea
Compare
Full Reportsanity
@sanity/diff
@sanity/block-tools
@sanity/types
sanity/desk
@sanity/portable-text-editor
@sanity/mutator
@sanity/cli
sanity/document
@sanity/schema/_internal
@sanity/util/paths
sanity/router
@sanity/util/legacyDateFormat
@sanity/schema
sanity/cli
@sanity/vision
@sanity/util/fs
sanity/_internal
@sanity/util/content
|
Component Testing Report Updated Sep 27, 2023 5:19 PM (UTC)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great! I love the general direction this is going.
Some quick general notes:
-
useFormState and useEditState feels very similar in nature and I think the existence of both might potentially add some confusion. Would it make sense to introduce an
useEditState
that takes no arguments and reads from a context provider instead? If so we can also consider removing providingeditState
from the FormStateProvider. The currentuseEditState(<id>, <type>)
is marked as internal, but I suspect it might be breaking to remove it, so perhaps it can be deprecated and still live on while we introduce a new one without any arguments? We might even be able to give the new one a better name. (Note: I don't have a crystal clear picture of whether this makes sense, so consider it with a grain of salt) -
Bug: When running the branch locally and I open a document, it loads fine, but after a few secs it goes back into loading state which stays forever.
-
See also inline comments.
import {EditStateFor, PermissionCheckResult} from '../../store' | ||
|
||
export interface FormStateContextValue<TDocument extends SanityDocumentLike> { | ||
documentId: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably document whether this is the draft id or published id
*/ | ||
value: TDocument | ||
|
||
editState: EditStateFor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use the opportunity to rename EditStateFor
=> DocumentEditState
?
|
||
/** | ||
* Signals when the document is ready for editing. Considers the connection | ||
* state, edit states, and whether or not the timeline is ready. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "edit states" refer to here? IIRC, the edit state is already a downstream dependency of connection state. Also wondering whether "timeline ready" state should be kept separate (e.g. we don't need the timeline to be ready in order to edit I believe)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bjoerge and i were talking about this in a meeting and we feel like ready
does not communicate exactly what is ready and we may rename this one.
/** | ||
* Propagates changes described by a patch event message to the form value. | ||
*/ | ||
patchValue: (event: PatchEvent) => void |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be named onPatchValue
or simply onPatch
to match already established conventions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bjoerge and I discussed this in a call as well and we think we like the convention handle-
instead of on
to signify that the caller can call this function instead of having to provide an implementation
formState: DocumentFormNode | null | ||
|
||
focusPath: Path | ||
setFocusPath: (path: Path) => void |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be named onPathFocus
for consistency with existing APIs
* it will be `historical-value`, if the value is from an initial value | ||
* template then it will be `initial-value` | ||
*/ | ||
valueOrigin: 'draft-value' | 'published-value' | 'initial-value' | 'historical-value' | undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would there be cases where you need a combination of several of these? I think it's great that we only have one value
to refer to as the document currently being edited, but wondering if it will make it hard to know e.g. whether there exists a published version of the draft currently being edited.
|
||
/** | ||
* if the value originates from the current value from context lake, then this | ||
* will be `current-value`. if the value is from a historical revision then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
current-value
isn't valid for valueOrigin
?
* it will be `historical-value`, if the value is from an initial value | ||
* template then it will be `initial-value` | ||
*/ | ||
valueOrigin: 'draft-value' | 'published-value' | 'initial-value' | 'historical-value' | undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be good to document what cases valueOrigin may be undefined
export function DocumentIdAndTypeProvider({ | ||
fallback, | ||
children, | ||
documentType: typeFromProps = '*', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does *
mean in this context? Could it be replaced by undefined
or null
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed. we shouldn't use constants and do string compares when we already have to do null checks
@@ -1,7 +1,7 @@ | |||
import {SanityClient} from '@sanity/client' | |||
import {IdPair} from '../types' | |||
|
|||
export function memoizeKeyGen(client: SanityClient, idPair: IdPair, typeName: string) { | |||
export function memoizeKeyGen(client: SanityClient, idPair: IdPair, typeName = '*'): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this create separate cache entries for the same document id? I.e. depending on whether or not we know the document type up-front? If so, I'm wondering if we should require the type to be known at this point and do the lookup at an earlier stage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self-note for future reference: i think this change is not necessary atm. this change was introduced to allow the useConnectionState
hook to not have a specified type however this may not be the time for that change so we'll add a onConnectionStateChanged
prop to the DocumentProvider
instead to make this work
f0dcfea
to
26fe228
Compare
26fe228
to
c5407b9
Compare
c5407b9
to
6d06af0
Compare
e7bf4c3
to
4151f2e
Compare
9caf5d8
to
691aad1
Compare
Description
This PR introduces a new provider called
DocumentProvider
, aiming to separate concerns and improve performance originally handled by theDocumentPaneProvider
. It shifts core logic from thedesk
package into thecore
package and serves as a top-level interface for multiple other providers.Context
The
DocumentPaneProvider
was identified as a performance bottleneck, updating too often and being depended upon by an increasing number of components. To solve this, we've split its responsibilities among more focused providers and moved the core logic from thedesk
package to thecore
package.Features
DocumentProvider
that serves as an interface for multiple other providers.DocumentPaneProvider
indesk
package toDocumentProvider
incore
package.Composition
The
DocumentProvider
is composed of the following providers:FormStateProvider
InitialValueProvider
ReferenceInputOptionsProvider
TimelineProvider
DocumentIdAndTypeProvider
New Hooks
Several new hooks are introduced to work with the providers:
useFormState
useInitialValue
useReferenceInputOptions
useTimeline
anduseTimelineSelector
useDocumentId
anduseDocumentType
Note: Some of these hooks have versions that previously existed without associated providers. The new hooks are exported under a new package subpath
sanity/document
.Example Usage
Here's how the new
DocumentProvider
is used alongsideDocumentPaneProvider
:And the internal composition of
DocumentProvider
:Migration Path
The only API here that's breaking is the internal
useDocumentPane
API which removes a lot of properties. Migrating involves using the newer hooks instead of just using theuseDocumentPane
API. The rest of this PR is more or less additive but I did deprecate with the@deprecate
ts doc tag.Form State Management
In addition to the the
DocumentProvider
, theFormStateProvider
updates the API related to form state within the DocumentProvider. Some properties were updated, renamed, or moved in order to increase clarity. Feel free to look at this in depth more.What to review
At this point, take a look at this PR conceptually and we can re-review with more details. This PR is still a bit early.
Notes for release
TBD.