@sanity/sdk-react 3.11.0-next.20261029105031 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +13 -9
  2. package/dist/_exports/collaboration.d.ts +255 -0
  3. package/dist/_exports/collaboration.d.ts.map +1 -0
  4. package/dist/_exports/collaboration.js +244 -0
  5. package/dist/_exports/collaboration.js.map +1 -0
  6. package/dist/_exports/dashboard.js +2 -1
  7. package/dist/_exports/dashboard.js.map +1 -1
  8. package/dist/index.d.ts +16 -22
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +49 -159
  11. package/dist/index.js.map +1 -1
  12. package/dist/useCommentList-CXi_IIwA.js +167 -0
  13. package/dist/useCommentList-CXi_IIwA.js.map +1 -0
  14. package/dist/useNormalizedResourceOptions-BKg7aOKA.d.ts +22 -0
  15. package/dist/useNormalizedResourceOptions-BKg7aOKA.d.ts.map +1 -0
  16. package/dist/useSanityInstance-C0a_Ou_p.js +10 -0
  17. package/dist/useSanityInstance-C0a_Ou_p.js.map +1 -0
  18. package/dist/{useStudioWorkspacesByProjectIdDataset-FRofq7KL.js → useStudioWorkspacesByProjectIdDataset-Cx-Q44d0.js} +4 -8
  19. package/dist/useStudioWorkspacesByProjectIdDataset-Cx-Q44d0.js.map +1 -0
  20. package/package.json +3 -2
  21. package/src/_exports/collaboration.ts +13 -0
  22. package/src/_exports/sdk-react.ts +6 -3
  23. package/src/hooks/comments/legacy/noCommentsError.ts +20 -0
  24. package/src/hooks/comments/legacy/useCommentActions.test.tsx +150 -0
  25. package/src/hooks/comments/legacy/useCommentActions.ts +116 -0
  26. package/src/hooks/comments/legacy/useCommentThreads.test.tsx +107 -0
  27. package/src/hooks/comments/legacy/useCommentThreads.ts +83 -0
  28. package/src/hooks/comments/legacy/useComments.test.tsx +242 -0
  29. package/src/hooks/comments/legacy/useComments.ts +68 -0
  30. package/src/hooks/comments/useCommentActions.test.tsx +33 -13
  31. package/src/hooks/comments/useCommentActions.ts +31 -11
  32. package/src/hooks/comments/useCommentList.ts +34 -19
  33. package/src/hooks/comments/useCommentThreads.test.tsx +207 -19
  34. package/src/hooks/comments/useCommentThreads.ts +33 -27
  35. package/src/hooks/comments/useComments.test.tsx +33 -126
  36. package/src/hooks/comments/useComments.ts +31 -12
  37. package/src/hooks/comments/useCommentsQuery.test.tsx +259 -0
  38. package/src/hooks/comments/useCommentsQuery.ts +105 -0
  39. package/src/hooks/document/useEditDocument.ts +0 -1
  40. package/dist/useStudioWorkspacesByProjectIdDataset-FRofq7KL.js.map +0 -1
package/README.md CHANGED
@@ -798,15 +798,18 @@ function DocStatus({handle}: {handle: DocumentHandle}) {
798
798
 
799
799
  ## Quick Reference
800
800
 
801
- | Task | Hook/Function |
802
- | --------------------- | ------------------------------------------- |
803
- | List documents | `useDocuments`, `usePaginatedDocuments` |
804
- | Read document | `useDocument`, `useDocumentProjection` |
805
- | Edit field | `useEditDocument` |
806
- | Publish/Delete/Create | `useApplyDocumentActions` + action creators |
807
- | GROQ query | `useQuery` |
808
- | Check permissions | `useDocumentPermissions` |
809
- | Listen to changes | `useDocumentEvent` |
801
+ | Task | Hook/Function |
802
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------- |
803
+ | List documents | `useDocuments`, `usePaginatedDocuments` |
804
+ | Read document | `useDocument`, `useDocumentProjection` |
805
+ | Edit field | `useEditDocument` |
806
+ | Publish/Delete/Create | `useApplyDocumentActions` + action creators |
807
+ | GROQ query | `useQuery` |
808
+ | Check permissions | `useDocumentPermissions` |
809
+ | Listen to changes | `useDocumentEvent` |
810
+ | Comments | `useComments`, `useCommentThreads`, `useCommentsQuery`, `useCommentActions`, from `@sanity/sdk-react/collaboration` |
811
+
812
+ Comments have their own guide: [Collaboration](./guides/Collaboration.md).
810
813
 
811
814
  ---
812
815
 
@@ -815,6 +818,7 @@ function DocStatus({handle}: {handle: DocumentHandle}) {
815
818
  - **[Sanity Docs](https://sanity.io/docs/app-sdk)** — Conceptual overview, quickstart guide, and step-by-step walkthrough
816
819
  - **[App SDK Reference](https://reference.sanity.io/_sanity/sdk-react)** — In-depth API documentation
817
820
  - **[SDK Explorer](https://sdk-explorer.sanity.io)** — Example implementations
821
+ - **[Collaboration Guide](./guides/Collaboration.md)** — Reading and writing comments
818
822
  - **[Migration Guide](./guides/0-Migration-Guide.md)** — Upgrading from previous versions
819
823
  - **[Learn Course](https://www.sanity.io/learn/course/build-content-apps-with-sanity-app-sdk)** — Interactive video tutorial
820
824
 
@@ -0,0 +1,255 @@
1
+ import { t as WithResourceNameSupport } from "../useNormalizedResourceOptions-BKg7aOKA.js";
2
+ import { Comment, CommentThread, CommentsOptions, CommentsQueryOptions, CreateCommentOptions, ReactionOptions, RemoveCommentOptions, ReplyToCommentOptions, SetCommentStatusOptions, UpdateCommentAnchorOptions, UpdateCommentOptions } from "@sanity/sdk/collaboration";
3
+ export * from "@sanity/sdk/collaboration";
4
+ /**
5
+ * @beta
6
+ * @category Types
7
+ * @category Comments
8
+ */
9
+ interface CommentActions {
10
+ /** Starts a thread on one of a document's fields. */
11
+ createComment: (options: WithResourceNameSupport<CreateCommentOptions>) => Promise<Comment>;
12
+ /** Adds a reply to an existing thread. */
13
+ replyToComment: (options: WithResourceNameSupport<ReplyToCommentOptions>) => Promise<Comment>;
14
+ /** Rewrites a comment's message. */
15
+ updateComment: (options: WithResourceNameSupport<UpdateCommentOptions>) => Promise<void>;
16
+ /**
17
+ * Re-anchors a comment to a different run of text, without marking it edited.
18
+ */
19
+ updateCommentAnchor: (options: WithResourceNameSupport<UpdateCommentAnchorOptions>) => Promise<void>;
20
+ /** Resolves or reopens a thread. Pass the thread's first comment. */
21
+ setCommentStatus: (options: WithResourceNameSupport<SetCommentStatusOptions>) => Promise<void>;
22
+ /** Deletes a comment, and its replies when it starts a thread. */
23
+ removeComment: (options: WithResourceNameSupport<RemoveCommentOptions>) => Promise<void>;
24
+ /** Adds the current user's reaction to a comment. */
25
+ addReaction: (options: WithResourceNameSupport<ReactionOptions>) => Promise<void>;
26
+ /** Removes the current user's reaction from a comment. */
27
+ removeReaction: (options: WithResourceNameSupport<ReactionOptions>) => Promise<void>;
28
+ }
29
+ /**
30
+ * Returns the comment write actions, bound to the current instance.
31
+ *
32
+ * Each writes optimistically: the change shows immediately and is rolled back
33
+ * if the server rejects it, so an app can render straight from
34
+ * {@link useCommentThreads} without tracking pending state itself.
35
+ *
36
+ * Creating is the exception, and `replyToComment` counts as creating. A comment
37
+ * that fails to post stays on screen carrying `state.createError` rather than
38
+ * disappearing, so passing the same `commentId` again retries it instead of
39
+ * losing what someone typed.
40
+ *
41
+ * The resource is resolved when an action is called rather than when the hook
42
+ * runs, so one set of callbacks works across several resources. Pass `resource`
43
+ * or `resourceName` per call to choose; otherwise the surrounding
44
+ * `ResourceProvider` decides. The organization the comments live in is
45
+ * resolved per call as well: the one the Dashboard opened the app in, else
46
+ * `organizationId` on the Sanity config, else the organization owning the
47
+ * resource's project. It cannot be passed on the call.
48
+ *
49
+ * @category Comments
50
+ * @function
51
+ * @returns The write actions
52
+ *
53
+ * @example Resolve a thread
54
+ * ```tsx
55
+ * function ResolveButton({commentId}: {commentId: string}) {
56
+ * const {setCommentStatus} = useCommentActions()
57
+ *
58
+ * return (
59
+ * <button onClick={() => setCommentStatus({commentId, status: 'resolved'})}>
60
+ * Resolve
61
+ * </button>
62
+ * )
63
+ * }
64
+ * ```
65
+ *
66
+ * @beta
67
+ */
68
+ export declare function useCommentActions(): CommentActions;
69
+ /**
70
+ * @beta
71
+ * @category Types
72
+ * @category Comments
73
+ */
74
+ interface UseCommentsResult {
75
+ /** Every matching comment, newest first, replies included. */
76
+ comments: Comment[];
77
+ /** True while switching to a different document or filter. */
78
+ isPending: boolean;
79
+ /**
80
+ * Set when the comments have stopped following the server: the listener
81
+ * failed after they had loaded, so what you are reading is the list as it
82
+ * last stood rather than as it is. Clears when a listener comes back.
83
+ */
84
+ error?: unknown;
85
+ }
86
+ /**
87
+ * Reads a document's comments and keeps them up to date.
88
+ *
89
+ * The list is flat, replies included, which suits a count or a feed. Reach for
90
+ * {@link useCommentThreads} to read the same comments grouped, where a reply
91
+ * sits under the comment it answers and filtering by `status` or `fieldPath`
92
+ * selects whole threads rather than individual comments. Both read the same
93
+ * document and share a listener, so using them side by side costs nothing
94
+ * extra. {@link useCommentsQuery} covers anything that is not one document's
95
+ * comments.
96
+ *
97
+ * Suspends until the comments have loaded. Switching document or filter is a
98
+ * transition, so the previous list stays on screen and `isPending` goes true
99
+ * rather than the component suspending again.
100
+ *
101
+ * @category Comments
102
+ * @function
103
+ * @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`
104
+ * @returns The matching comments, and whether a switch is in flight
105
+ *
106
+ * @example Count the open comments on a field
107
+ * ```tsx
108
+ * function TitleCommentCount({documentId}: {documentId: string}) {
109
+ * const {comments} = useComments({
110
+ * documentId,
111
+ * documentType: 'article',
112
+ * fieldPath: 'title',
113
+ * status: 'open',
114
+ * })
115
+ *
116
+ * return <span>{comments.length}</span>
117
+ * }
118
+ * ```
119
+ *
120
+ * @beta
121
+ */
122
+ export declare function useComments(options: WithResourceNameSupport<CommentsOptions>): UseCommentsResult;
123
+ /**
124
+ * @beta
125
+ * @category Types
126
+ */
127
+ interface UseCommentsQueryResult {
128
+ /** Every matching comment, newest first, replies included. */
129
+ comments: Comment[];
130
+ /** True while switching to a different filter. */
131
+ isPending: boolean;
132
+ /**
133
+ * Set when the comments have stopped following the server: the listener
134
+ * failed after they had loaded, so what you are reading is the list as it
135
+ * last stood rather than as it is. Clears when a listener comes back.
136
+ */
137
+ error?: unknown;
138
+ }
139
+ /**
140
+ * Reads comments matching a GROQ filter and keeps them up to date.
141
+ *
142
+ * The escape hatch for anything that is not "comments on this document":
143
+ * cross-document views, per-user views, organization-wide activity. The list is
144
+ * flat, replies included; reach for {@link useCommentThreads} to read one
145
+ * document's comments grouped into threads.
146
+ *
147
+ * `_type == "sanity.comment"` is applied for you. Comments are stored per
148
+ * organization, resolved rather than configured: the one the Dashboard opened
149
+ * the app in, else `organizationId` on the Sanity config, else the organization
150
+ * owning the resource's project. The filter runs over every comment that
151
+ * organization can read, not only the ones in the resource's dataset: comment
152
+ * queries are routed by organization and the resource is not sent with them.
153
+ * To keep to one dataset, add a `target.document._ref` prefix condition
154
+ * yourself. Refs are `dataset:{projectId}.{dataset}:{documentId}`.
155
+ *
156
+ * Suspends until the comments have loaded. Switching filter is a transition, so
157
+ * the previous list stays on screen and `isPending` goes true rather than the
158
+ * component suspending again.
159
+ *
160
+ * Writes show here before the server confirms them, the same as they do on a
161
+ * document's comments, because the filter is matched against the written
162
+ * comment locally. That holds for writes through the resource the query is
163
+ * bound to; comments written through another dataset arrive once the server
164
+ * confirms them. A filter that cannot be answered that way — one that
165
+ * dereferences, runs a `*[...]` of its own, or calls a context-dependent
166
+ * function such as `sanity::dataset()` or `now()` — still works, but only
167
+ * follows the server, and costs a connection of its own rather than sharing one.
168
+ *
169
+ * @category Comments
170
+ * @function
171
+ * @param options - The GROQ `filter` to match, and any `params` it reads
172
+ * @returns The matching comments, and whether a switch is in flight
173
+ *
174
+ * @example Every comment mentioning the current user
175
+ * ```tsx
176
+ * function Mentions({userId}: {userId: string}) {
177
+ * const {comments} = useCommentsQuery({
178
+ * filter: 'count(message[].children[_type == "mention" && userId == $userId]) > 0',
179
+ * params: {userId},
180
+ * })
181
+ *
182
+ * return <span>{comments.length}</span>
183
+ * }
184
+ * ```
185
+ *
186
+ * @example Open comments in one dataset
187
+ * ```tsx
188
+ * function OpenInProduction() {
189
+ * const {comments} = useCommentsQuery({
190
+ * filter: 'string::startsWith(target.document._ref, $prefix) && status == "open"',
191
+ * params: {prefix: 'dataset:abc123.production:'},
192
+ * })
193
+ *
194
+ * return <span>{comments.length}</span>
195
+ * }
196
+ * ```
197
+ *
198
+ * @beta
199
+ */
200
+ export declare function useCommentsQuery(options: WithResourceNameSupport<CommentsQueryOptions>): UseCommentsQueryResult;
201
+ /**
202
+ * @beta
203
+ * @category Types
204
+ * @category Comments
205
+ */
206
+ interface UseCommentThreadsResult {
207
+ /** Matching threads, newest first, each with its replies oldest first. */
208
+ threads: CommentThread[];
209
+ /** True while switching to a different document or filter. */
210
+ isPending: boolean;
211
+ /**
212
+ * Set when the threads have stopped following the server: the listener
213
+ * failed after they had loaded, so what you are reading is the list as it
214
+ * last stood rather than as it is. Clears when a listener comes back.
215
+ */
216
+ error?: unknown;
217
+ }
218
+ /**
219
+ * Reads a document's comment threads and keeps them up to date.
220
+ *
221
+ * A thread carries its first comment plus its replies, and `status` and
222
+ * `fieldPath` come from that first comment, so filtering by either selects
223
+ * whole threads. Use {@link useComments} to read the same list flat, `scope` to
224
+ * say which of the document's comments to cover — by default it follows the
225
+ * perspective in view — and {@link useCommentsQuery} when the question is not
226
+ * "comments on this document".
227
+ *
228
+ * Suspends until the comments have loaded. Switching document or filter is a
229
+ * transition, so the previous list stays on screen and `isPending` goes true
230
+ * rather than the component suspending again.
231
+ *
232
+ * @category Comments
233
+ * @function
234
+ * @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`
235
+ * @returns The matching threads, and whether a switch is in flight
236
+ *
237
+ * @example Count the open threads on a field
238
+ * ```tsx
239
+ * function TitleCommentCount({documentId}: {documentId: string}) {
240
+ * const {threads} = useCommentThreads({
241
+ * documentId,
242
+ * documentType: 'article',
243
+ * fieldPath: 'title',
244
+ * status: 'open',
245
+ * })
246
+ *
247
+ * return <span>{threads.length}</span>
248
+ * }
249
+ * ```
250
+ *
251
+ * @beta
252
+ */
253
+ export declare function useCommentThreads(options: WithResourceNameSupport<CommentsOptions>): UseCommentThreadsResult;
254
+ export type { CommentActions, UseCommentThreadsResult, UseCommentsQueryResult, UseCommentsResult };
255
+ //# sourceMappingURL=collaboration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collaboration.d.ts","names":["Comment","CreateCommentOptions","ReactionOptions","RemoveCommentOptions","ReplyToCommentOptions","SetCommentStatusOptions","UpdateCommentAnchorOptions","UpdateCommentOptions","WithResourceNameSupport","CommentActions","Promise","useCommentActions","Comment","CommentsOptions","WithResourceNameSupport","UseCommentsResult","useComments","Comment","CommentsQueryOptions","WithResourceNameSupport","UseCommentsQueryResult","useCommentsQuery","CommentsOptions","CommentThread","WithResourceNameSupport","UseCommentThreadsResult","useCommentThreads"],"sources":["../../src/hooks/comments/useCommentActions.ts","../../src/hooks/comments/useComments.ts","../../src/hooks/comments/useCommentsQuery.ts","../../src/hooks/comments/useCommentThreads.ts"],"mappings":";;;;;;;;UAoCiBS;;EAEf,gBAAgB,SAASD,wBAAwBP,0BAA0BS,QAAQV;;EAEnF,iBAAiB,SAASQ,wBAAwBJ,2BAA2BM,QAAQV;;EAErF,gBAAgB,SAASQ,wBAAwBD,0BAA0BG;;;;EAI3E,sBACE,SAASF,wBAAwBF,gCAC9BI;;EAEL,mBAAmB,SAASF,wBAAwBH,6BAA6BK;;EAEjF,gBAAgB,SAASF,wBAAwBL,0BAA0BO;;EAE3E,cAAc,SAASF,wBAAwBN,qBAAqBQ;;EAEpE,iBAAiB,SAASF,wBAAwBN,qBAAqBQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAkDzDC,qBAAqBF;;;;;;UCxFpBM;;EAEf,UAAUH;;EAEV;;;;;;EAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA+CcI,YAAY,SAASF,wBAAwBD,mBAAmBE;;;;;UC1D/DK;;EAEf,UAAUH;;EAEV;;;;;;EAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAwEcI,iBACd,SAASF,wBAAwBD,wBAChCE;;;;;;UCnFcK;;EAEf,SAASF;;EAET;;;;;;EAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA8CcG,kBACd,SAASF,wBAAwBF,mBAChCG"}
@@ -0,0 +1,244 @@
1
+ import { t as useSanityInstance } from "../useSanityInstance-C0a_Ou_p.js";
2
+ import { a as useEffectiveContextResource, i as normalizeResourceOptions, l as ResourcesContext, n as trackHookUsage, s as PerspectiveContext, t as useCommentList } from "../useCommentList-CXi_IIwA.js";
3
+ import { c } from "react-compiler-runtime";
4
+ import "@sanity/sdk";
5
+ import { getCommentsQueryOptionsKey, getDocumentCommentsOptionsKey, parseCommentsQueryOptionsKey, parseDocumentCommentsOptionsKey } from "@sanity/sdk/_internal";
6
+ import { useContext } from "react";
7
+ import { addReaction, createComment as createComment$1, getCommentThreadsState as getCommentThreadsState$1, getCommentsErrorState, getCommentsQueryErrorState, getCommentsQueryState, getCommentsState as getCommentsState$1, removeComment as removeComment$1, removeReaction, replyToComment as replyToComment$1, resolveCommentThreads as resolveCommentThreads$1, resolveComments as resolveComments$1, resolveCommentsQuery, setCommentStatus as setCommentStatus$1, updateComment as updateComment$1, updateCommentAnchor } from "@sanity/sdk/collaboration";
8
+ export * from "@sanity/sdk/collaboration";
9
+ /**
10
+ * Returns the comment write actions, bound to the current instance.
11
+ *
12
+ * Each writes optimistically: the change shows immediately and is rolled back
13
+ * if the server rejects it, so an app can render straight from
14
+ * {@link useCommentThreads} without tracking pending state itself.
15
+ *
16
+ * Creating is the exception, and `replyToComment` counts as creating. A comment
17
+ * that fails to post stays on screen carrying `state.createError` rather than
18
+ * disappearing, so passing the same `commentId` again retries it instead of
19
+ * losing what someone typed.
20
+ *
21
+ * The resource is resolved when an action is called rather than when the hook
22
+ * runs, so one set of callbacks works across several resources. Pass `resource`
23
+ * or `resourceName` per call to choose; otherwise the surrounding
24
+ * `ResourceProvider` decides. The organization the comments live in is
25
+ * resolved per call as well: the one the Dashboard opened the app in, else
26
+ * `organizationId` on the Sanity config, else the organization owning the
27
+ * resource's project. It cannot be passed on the call.
28
+ *
29
+ * @category Comments
30
+ * @function
31
+ * @returns The write actions
32
+ *
33
+ * @example Resolve a thread
34
+ * ```tsx
35
+ * function ResolveButton({commentId}: {commentId: string}) {
36
+ * const {setCommentStatus} = useCommentActions()
37
+ *
38
+ * return (
39
+ * <button onClick={() => setCommentStatus({commentId, status: 'resolved'})}>
40
+ * Resolve
41
+ * </button>
42
+ * )
43
+ * }
44
+ * ```
45
+ *
46
+ * @beta
47
+ */
48
+ function useCommentActions() {
49
+ let $ = c(7), instance = useSanityInstance();
50
+ trackHookUsage(instance, "useCommentActions");
51
+ let resources = useContext(ResourcesContext), contextResource = useEffectiveContextResource(), contextPerspective = useContext(PerspectiveContext), t0;
52
+ $[0] !== contextPerspective || $[1] !== contextResource || $[2] !== resources ? (t0 = (options) => normalizeResourceOptions(options, resources, contextResource, contextPerspective), $[0] = contextPerspective, $[1] = contextResource, $[2] = resources, $[3] = t0) : t0 = $[3];
53
+ let resolve = t0, t1;
54
+ return $[4] !== instance || $[5] !== resolve ? (t1 = {
55
+ createComment: (options_0) => createComment$1(instance, resolve(options_0)),
56
+ replyToComment: (options_1) => replyToComment$1(instance, resolve(options_1)),
57
+ updateComment: (options_2) => updateComment$1(instance, resolve(options_2)),
58
+ updateCommentAnchor: (options_3) => updateCommentAnchor(instance, resolve(options_3)),
59
+ setCommentStatus: (options_4) => setCommentStatus$1(instance, resolve(options_4)),
60
+ removeComment: (options_5) => removeComment$1(instance, resolve(options_5)),
61
+ addReaction: (options_6) => addReaction(instance, resolve(options_6)),
62
+ removeReaction: (options_7) => removeReaction(instance, resolve(options_7))
63
+ }, $[4] = instance, $[5] = resolve, $[6] = t1) : t1 = $[6], t1;
64
+ }
65
+ const SOURCE$2 = {
66
+ getState: getCommentsState$1,
67
+ getErrorState: getCommentsErrorState,
68
+ resolve: resolveComments$1,
69
+ getKey: getDocumentCommentsOptionsKey,
70
+ parseKey: parseDocumentCommentsOptionsKey
71
+ };
72
+ /**
73
+ * Reads a document's comments and keeps them up to date.
74
+ *
75
+ * The list is flat, replies included, which suits a count or a feed. Reach for
76
+ * {@link useCommentThreads} to read the same comments grouped, where a reply
77
+ * sits under the comment it answers and filtering by `status` or `fieldPath`
78
+ * selects whole threads rather than individual comments. Both read the same
79
+ * document and share a listener, so using them side by side costs nothing
80
+ * extra. {@link useCommentsQuery} covers anything that is not one document's
81
+ * comments.
82
+ *
83
+ * Suspends until the comments have loaded. Switching document or filter is a
84
+ * transition, so the previous list stays on screen and `isPending` goes true
85
+ * rather than the component suspending again.
86
+ *
87
+ * @category Comments
88
+ * @function
89
+ * @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`
90
+ * @returns The matching comments, and whether a switch is in flight
91
+ *
92
+ * @example Count the open comments on a field
93
+ * ```tsx
94
+ * function TitleCommentCount({documentId}: {documentId: string}) {
95
+ * const {comments} = useComments({
96
+ * documentId,
97
+ * documentType: 'article',
98
+ * fieldPath: 'title',
99
+ * status: 'open',
100
+ * })
101
+ *
102
+ * return <span>{comments.length}</span>
103
+ * }
104
+ * ```
105
+ *
106
+ * @beta
107
+ */
108
+ function useComments(options) {
109
+ let $ = c(4), { value, isPending, error } = useCommentList("useComments", options, SOURCE$2), t0;
110
+ return $[0] !== error || $[1] !== isPending || $[2] !== value ? (t0 = {
111
+ comments: value,
112
+ isPending,
113
+ error
114
+ }, $[0] = error, $[1] = isPending, $[2] = value, $[3] = t0) : t0 = $[3], t0;
115
+ }
116
+ const SOURCE$1 = {
117
+ getState: getCommentsQueryState,
118
+ getErrorState: getCommentsQueryErrorState,
119
+ resolve: resolveCommentsQuery,
120
+ getKey: getCommentsQueryOptionsKey,
121
+ parseKey: parseCommentsQueryOptionsKey
122
+ };
123
+ /**
124
+ * Reads comments matching a GROQ filter and keeps them up to date.
125
+ *
126
+ * The escape hatch for anything that is not "comments on this document":
127
+ * cross-document views, per-user views, organization-wide activity. The list is
128
+ * flat, replies included; reach for {@link useCommentThreads} to read one
129
+ * document's comments grouped into threads.
130
+ *
131
+ * `_type == "sanity.comment"` is applied for you. Comments are stored per
132
+ * organization, resolved rather than configured: the one the Dashboard opened
133
+ * the app in, else `organizationId` on the Sanity config, else the organization
134
+ * owning the resource's project. The filter runs over every comment that
135
+ * organization can read, not only the ones in the resource's dataset: comment
136
+ * queries are routed by organization and the resource is not sent with them.
137
+ * To keep to one dataset, add a `target.document._ref` prefix condition
138
+ * yourself. Refs are `dataset:{projectId}.{dataset}:{documentId}`.
139
+ *
140
+ * Suspends until the comments have loaded. Switching filter is a transition, so
141
+ * the previous list stays on screen and `isPending` goes true rather than the
142
+ * component suspending again.
143
+ *
144
+ * Writes show here before the server confirms them, the same as they do on a
145
+ * document's comments, because the filter is matched against the written
146
+ * comment locally. That holds for writes through the resource the query is
147
+ * bound to; comments written through another dataset arrive once the server
148
+ * confirms them. A filter that cannot be answered that way — one that
149
+ * dereferences, runs a `*[...]` of its own, or calls a context-dependent
150
+ * function such as `sanity::dataset()` or `now()` — still works, but only
151
+ * follows the server, and costs a connection of its own rather than sharing one.
152
+ *
153
+ * @category Comments
154
+ * @function
155
+ * @param options - The GROQ `filter` to match, and any `params` it reads
156
+ * @returns The matching comments, and whether a switch is in flight
157
+ *
158
+ * @example Every comment mentioning the current user
159
+ * ```tsx
160
+ * function Mentions({userId}: {userId: string}) {
161
+ * const {comments} = useCommentsQuery({
162
+ * filter: 'count(message[].children[_type == "mention" && userId == $userId]) > 0',
163
+ * params: {userId},
164
+ * })
165
+ *
166
+ * return <span>{comments.length}</span>
167
+ * }
168
+ * ```
169
+ *
170
+ * @example Open comments in one dataset
171
+ * ```tsx
172
+ * function OpenInProduction() {
173
+ * const {comments} = useCommentsQuery({
174
+ * filter: 'string::startsWith(target.document._ref, $prefix) && status == "open"',
175
+ * params: {prefix: 'dataset:abc123.production:'},
176
+ * })
177
+ *
178
+ * return <span>{comments.length}</span>
179
+ * }
180
+ * ```
181
+ *
182
+ * @beta
183
+ */
184
+ function useCommentsQuery(options) {
185
+ let $ = c(4), { value, isPending, error } = useCommentList("useCommentsQuery", options, SOURCE$1), t0;
186
+ return $[0] !== error || $[1] !== isPending || $[2] !== value ? (t0 = {
187
+ comments: value,
188
+ isPending,
189
+ error
190
+ }, $[0] = error, $[1] = isPending, $[2] = value, $[3] = t0) : t0 = $[3], t0;
191
+ }
192
+ const SOURCE = {
193
+ getState: getCommentThreadsState$1,
194
+ getErrorState: getCommentsErrorState,
195
+ resolve: resolveCommentThreads$1,
196
+ getKey: getDocumentCommentsOptionsKey,
197
+ parseKey: parseDocumentCommentsOptionsKey
198
+ };
199
+ /**
200
+ * Reads a document's comment threads and keeps them up to date.
201
+ *
202
+ * A thread carries its first comment plus its replies, and `status` and
203
+ * `fieldPath` come from that first comment, so filtering by either selects
204
+ * whole threads. Use {@link useComments} to read the same list flat, `scope` to
205
+ * say which of the document's comments to cover — by default it follows the
206
+ * perspective in view — and {@link useCommentsQuery} when the question is not
207
+ * "comments on this document".
208
+ *
209
+ * Suspends until the comments have loaded. Switching document or filter is a
210
+ * transition, so the previous list stays on screen and `isPending` goes true
211
+ * rather than the component suspending again.
212
+ *
213
+ * @category Comments
214
+ * @function
215
+ * @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`
216
+ * @returns The matching threads, and whether a switch is in flight
217
+ *
218
+ * @example Count the open threads on a field
219
+ * ```tsx
220
+ * function TitleCommentCount({documentId}: {documentId: string}) {
221
+ * const {threads} = useCommentThreads({
222
+ * documentId,
223
+ * documentType: 'article',
224
+ * fieldPath: 'title',
225
+ * status: 'open',
226
+ * })
227
+ *
228
+ * return <span>{threads.length}</span>
229
+ * }
230
+ * ```
231
+ *
232
+ * @beta
233
+ */
234
+ function useCommentThreads(options) {
235
+ let $ = c(4), { value, isPending, error } = useCommentList("useCommentThreads", options, SOURCE), t0;
236
+ return $[0] !== error || $[1] !== isPending || $[2] !== value ? (t0 = {
237
+ threads: value,
238
+ isPending,
239
+ error
240
+ }, $[0] = error, $[1] = isPending, $[2] = value, $[3] = t0) : t0 = $[3], t0;
241
+ }
242
+ export { useCommentActions, useCommentThreads, useComments, useCommentsQuery };
243
+
244
+ //# sourceMappingURL=collaboration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collaboration.js","names":["DocumentResource","PerspectiveHandle","addReaction","Comment","createComment","CreateCommentOptions","ReactionOptions","removeComment","RemoveCommentOptions","removeReaction","replyToComment","ReplyToCommentOptions","setCommentStatus","SetCommentStatusOptions","updateComment","updateCommentAnchor","UpdateCommentAnchorOptions","UpdateCommentOptions","useContext","useMemo","PerspectiveContext","ResourcesContext","useSanityInstance","normalizeResourceOptions","useEffectiveContextResource","WithResourceNameSupport","trackHookUsage","CommentActions","options","Promise","Resolvable","resource","resourceName","projectId","dataset","perspective","useCommentActions","$","_c","instance","resources","contextResource","contextPerspective","t0","resolve","t1","options_0","options_1","options_2","options_3","options_4","options_5","options_6","options_7","_c","createComment","replyToComment","updateComment","setCommentStatus","removeComment","getDocumentCommentsOptionsKey","parseDocumentCommentsOptionsKey","Comment","CommentsOptions","getCommentsErrorState","getCommentsState","resolveComments","useMemo","WithResourceNameSupport","CommentListSource","useCommentList","UseCommentsResult","comments","isPending","error","SOURCE","getState","getErrorState","resolve","getKey","parseKey","useComments","options","$","_c","value","t0","SOURCE","getCommentsState","resolveComments","_c","getCommentsQueryOptionsKey","parseCommentsQueryOptionsKey","Comment","CommentsQueryOptions","getCommentsQueryErrorState","getCommentsQueryState","resolveCommentsQuery","useMemo","WithResourceNameSupport","CommentListSource","useCommentList","UseCommentsQueryResult","comments","isPending","error","SOURCE","getState","getErrorState","resolve","getKey","parseKey","useCommentsQuery","options","$","_c","value","t0","SOURCE","_c","getDocumentCommentsOptionsKey","parseDocumentCommentsOptionsKey","CommentsOptions","CommentThread","getCommentsErrorState","getCommentThreadsState","resolveCommentThreads","useMemo","WithResourceNameSupport","CommentListSource","useCommentList","UseCommentThreadsResult","threads","isPending","error","SOURCE","getState","getErrorState","resolve","getKey","parseKey","useCommentThreads","options","$","_c","value","t0","getCommentThreadsState","resolveCommentThreads","_c"],"sources":["../../src/hooks/comments/useCommentActions.ts","../../src/hooks/comments/useComments.ts","../../src/hooks/comments/useCommentsQuery.ts","../../src/hooks/comments/useCommentThreads.ts"],"sourcesContent":["import {type DocumentResource, type PerspectiveHandle} from '@sanity/sdk'\nimport {\n addReaction,\n type Comment,\n createComment,\n type CreateCommentOptions,\n type ReactionOptions,\n removeComment,\n type RemoveCommentOptions,\n removeReaction,\n replyToComment,\n type ReplyToCommentOptions,\n setCommentStatus,\n type SetCommentStatusOptions,\n updateComment,\n updateCommentAnchor,\n type UpdateCommentAnchorOptions,\n type UpdateCommentOptions,\n} from '@sanity/sdk/collaboration'\nimport {useContext, useMemo} from 'react'\n\nimport {PerspectiveContext} from '../../context/PerspectiveContext'\nimport {ResourcesContext} from '../../context/ResourcesContext'\nimport {useSanityInstance} from '../context/useSanityInstance'\nimport {\n normalizeResourceOptions,\n useEffectiveContextResource,\n type WithResourceNameSupport,\n} from '../helpers/useNormalizedResourceOptions'\nimport {trackHookUsage} from '../helpers/useTrackHookUsage'\n\n/**\n * @beta\n * @category Types\n * @category Comments\n */\nexport interface CommentActions {\n /** Starts a thread on one of a document's fields. */\n createComment: (options: WithResourceNameSupport<CreateCommentOptions>) => Promise<Comment>\n /** Adds a reply to an existing thread. */\n replyToComment: (options: WithResourceNameSupport<ReplyToCommentOptions>) => Promise<Comment>\n /** Rewrites a comment's message. */\n updateComment: (options: WithResourceNameSupport<UpdateCommentOptions>) => Promise<void>\n /**\n * Re-anchors a comment to a different run of text, without marking it edited.\n */\n updateCommentAnchor: (\n options: WithResourceNameSupport<UpdateCommentAnchorOptions>,\n ) => Promise<void>\n /** Resolves or reopens a thread. Pass the thread's first comment. */\n setCommentStatus: (options: WithResourceNameSupport<SetCommentStatusOptions>) => Promise<void>\n /** Deletes a comment, and its replies when it starts a thread. */\n removeComment: (options: WithResourceNameSupport<RemoveCommentOptions>) => Promise<void>\n /** Adds the current user's reaction to a comment. */\n addReaction: (options: WithResourceNameSupport<ReactionOptions>) => Promise<void>\n /** Removes the current user's reaction from a comment. */\n removeReaction: (options: WithResourceNameSupport<ReactionOptions>) => Promise<void>\n}\n\ntype Resolvable = {\n resource?: DocumentResource\n resourceName?: string\n projectId?: string\n dataset?: string\n perspective?: PerspectiveHandle['perspective']\n}\n\n/**\n * Returns the comment write actions, bound to the current instance.\n *\n * Each writes optimistically: the change shows immediately and is rolled back\n * if the server rejects it, so an app can render straight from\n * {@link useCommentThreads} without tracking pending state itself.\n *\n * Creating is the exception, and `replyToComment` counts as creating. A comment\n * that fails to post stays on screen carrying `state.createError` rather than\n * disappearing, so passing the same `commentId` again retries it instead of\n * losing what someone typed.\n *\n * The resource is resolved when an action is called rather than when the hook\n * runs, so one set of callbacks works across several resources. Pass `resource`\n * or `resourceName` per call to choose; otherwise the surrounding\n * `ResourceProvider` decides. The organization the comments live in is\n * resolved per call as well: the one the Dashboard opened the app in, else\n * `organizationId` on the Sanity config, else the organization owning the\n * resource's project. It cannot be passed on the call.\n *\n * @category Comments\n * @function\n * @returns The write actions\n *\n * @example Resolve a thread\n * ```tsx\n * function ResolveButton({commentId}: {commentId: string}) {\n * const {setCommentStatus} = useCommentActions()\n *\n * return (\n * <button onClick={() => setCommentStatus({commentId, status: 'resolved'})}>\n * Resolve\n * </button>\n * )\n * }\n * ```\n *\n * @beta\n */\nexport function useCommentActions(): CommentActions {\n const instance = useSanityInstance()\n trackHookUsage(instance, 'useCommentActions')\n\n const resources = useContext(ResourcesContext)\n const contextResource = useEffectiveContextResource()\n const contextPerspective = useContext(PerspectiveContext)\n\n return useMemo(() => {\n const resolve = <T extends Resolvable>(options: T) =>\n normalizeResourceOptions(options, resources, contextResource, contextPerspective)\n\n return {\n createComment: (options) => createComment(instance, resolve(options)),\n replyToComment: (options) => replyToComment(instance, resolve(options)),\n updateComment: (options) => updateComment(instance, resolve(options)),\n updateCommentAnchor: (options) => updateCommentAnchor(instance, resolve(options)),\n setCommentStatus: (options) => setCommentStatus(instance, resolve(options)),\n removeComment: (options) => removeComment(instance, resolve(options)),\n addReaction: (options) => addReaction(instance, resolve(options)),\n removeReaction: (options) => removeReaction(instance, resolve(options)),\n }\n }, [contextPerspective, contextResource, instance, resources])\n}\n","import {getDocumentCommentsOptionsKey, parseDocumentCommentsOptionsKey} from '@sanity/sdk/_internal'\nimport {\n type Comment,\n type CommentsOptions,\n getCommentsErrorState,\n getCommentsState,\n resolveComments,\n} from '@sanity/sdk/collaboration'\nimport {useMemo} from 'react'\n\nimport {type WithResourceNameSupport} from '../helpers/useNormalizedResourceOptions'\nimport {type CommentListSource, useCommentList} from './useCommentList'\n\n/**\n * @beta\n * @category Types\n * @category Comments\n */\nexport interface UseCommentsResult {\n /** Every matching comment, newest first, replies included. */\n comments: Comment[]\n /** True while switching to a different document or filter. */\n isPending: boolean\n /**\n * Set when the comments have stopped following the server: the listener\n * failed after they had loaded, so what you are reading is the list as it\n * last stood rather than as it is. Clears when a listener comes back.\n */\n error?: unknown\n}\n\nconst SOURCE: CommentListSource<CommentsOptions, Comment[]> = {\n getState: getCommentsState,\n getErrorState: getCommentsErrorState,\n resolve: resolveComments,\n getKey: getDocumentCommentsOptionsKey,\n parseKey: parseDocumentCommentsOptionsKey,\n}\n\n/**\n * Reads a document's comments and keeps them up to date.\n *\n * The list is flat, replies included, which suits a count or a feed. Reach for\n * {@link useCommentThreads} to read the same comments grouped, where a reply\n * sits under the comment it answers and filtering by `status` or `fieldPath`\n * selects whole threads rather than individual comments. Both read the same\n * document and share a listener, so using them side by side costs nothing\n * extra. {@link useCommentsQuery} covers anything that is not one document's\n * comments.\n *\n * Suspends until the comments have loaded. Switching document or filter is a\n * transition, so the previous list stays on screen and `isPending` goes true\n * rather than the component suspending again.\n *\n * @category Comments\n * @function\n * @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`\n * @returns The matching comments, and whether a switch is in flight\n *\n * @example Count the open comments on a field\n * ```tsx\n * function TitleCommentCount({documentId}: {documentId: string}) {\n * const {comments} = useComments({\n * documentId,\n * documentType: 'article',\n * fieldPath: 'title',\n * status: 'open',\n * })\n *\n * return <span>{comments.length}</span>\n * }\n * ```\n *\n * @beta\n */\nexport function useComments(options: WithResourceNameSupport<CommentsOptions>): UseCommentsResult {\n const {value, isPending, error} = useCommentList('useComments', options, SOURCE)\n return useMemo(() => ({comments: value, isPending, error}), [error, isPending, value])\n}\n","import {getCommentsQueryOptionsKey, parseCommentsQueryOptionsKey} from '@sanity/sdk/_internal'\nimport {\n type Comment,\n type CommentsQueryOptions,\n getCommentsQueryErrorState,\n getCommentsQueryState,\n resolveCommentsQuery,\n} from '@sanity/sdk/collaboration'\nimport {useMemo} from 'react'\n\nimport {type WithResourceNameSupport} from '../helpers/useNormalizedResourceOptions'\nimport {type CommentListSource, useCommentList} from './useCommentList'\n\n/**\n * @beta\n * @category Types\n */\nexport interface UseCommentsQueryResult {\n /** Every matching comment, newest first, replies included. */\n comments: Comment[]\n /** True while switching to a different filter. */\n isPending: boolean\n /**\n * Set when the comments have stopped following the server: the listener\n * failed after they had loaded, so what you are reading is the list as it\n * last stood rather than as it is. Clears when a listener comes back.\n */\n error?: unknown\n}\n\nconst SOURCE: CommentListSource<CommentsQueryOptions, Comment[]> = {\n getState: getCommentsQueryState,\n getErrorState: getCommentsQueryErrorState,\n resolve: resolveCommentsQuery,\n getKey: getCommentsQueryOptionsKey,\n parseKey: parseCommentsQueryOptionsKey,\n}\n\n/**\n * Reads comments matching a GROQ filter and keeps them up to date.\n *\n * The escape hatch for anything that is not \"comments on this document\":\n * cross-document views, per-user views, organization-wide activity. The list is\n * flat, replies included; reach for {@link useCommentThreads} to read one\n * document's comments grouped into threads.\n *\n * `_type == \"sanity.comment\"` is applied for you. Comments are stored per\n * organization, resolved rather than configured: the one the Dashboard opened\n * the app in, else `organizationId` on the Sanity config, else the organization\n * owning the resource's project. The filter runs over every comment that\n * organization can read, not only the ones in the resource's dataset: comment\n * queries are routed by organization and the resource is not sent with them.\n * To keep to one dataset, add a `target.document._ref` prefix condition\n * yourself. Refs are `dataset:{projectId}.{dataset}:{documentId}`.\n *\n * Suspends until the comments have loaded. Switching filter is a transition, so\n * the previous list stays on screen and `isPending` goes true rather than the\n * component suspending again.\n *\n * Writes show here before the server confirms them, the same as they do on a\n * document's comments, because the filter is matched against the written\n * comment locally. That holds for writes through the resource the query is\n * bound to; comments written through another dataset arrive once the server\n * confirms them. A filter that cannot be answered that way — one that\n * dereferences, runs a `*[...]` of its own, or calls a context-dependent\n * function such as `sanity::dataset()` or `now()` — still works, but only\n * follows the server, and costs a connection of its own rather than sharing one.\n *\n * @category Comments\n * @function\n * @param options - The GROQ `filter` to match, and any `params` it reads\n * @returns The matching comments, and whether a switch is in flight\n *\n * @example Every comment mentioning the current user\n * ```tsx\n * function Mentions({userId}: {userId: string}) {\n * const {comments} = useCommentsQuery({\n * filter: 'count(message[].children[_type == \"mention\" && userId == $userId]) > 0',\n * params: {userId},\n * })\n *\n * return <span>{comments.length}</span>\n * }\n * ```\n *\n * @example Open comments in one dataset\n * ```tsx\n * function OpenInProduction() {\n * const {comments} = useCommentsQuery({\n * filter: 'string::startsWith(target.document._ref, $prefix) && status == \"open\"',\n * params: {prefix: 'dataset:abc123.production:'},\n * })\n *\n * return <span>{comments.length}</span>\n * }\n * ```\n *\n * @beta\n */\nexport function useCommentsQuery(\n options: WithResourceNameSupport<CommentsQueryOptions>,\n): UseCommentsQueryResult {\n const {value, isPending, error} = useCommentList('useCommentsQuery', options, SOURCE)\n return useMemo(() => ({comments: value, isPending, error}), [error, isPending, value])\n}\n","import {getDocumentCommentsOptionsKey, parseDocumentCommentsOptionsKey} from '@sanity/sdk/_internal'\nimport {\n type CommentsOptions,\n type CommentThread,\n getCommentsErrorState,\n getCommentThreadsState,\n resolveCommentThreads,\n} from '@sanity/sdk/collaboration'\nimport {useMemo} from 'react'\n\nimport {type WithResourceNameSupport} from '../helpers/useNormalizedResourceOptions'\nimport {type CommentListSource, useCommentList} from './useCommentList'\n\n/**\n * @beta\n * @category Types\n * @category Comments\n */\nexport interface UseCommentThreadsResult {\n /** Matching threads, newest first, each with its replies oldest first. */\n threads: CommentThread[]\n /** True while switching to a different document or filter. */\n isPending: boolean\n /**\n * Set when the threads have stopped following the server: the listener\n * failed after they had loaded, so what you are reading is the list as it\n * last stood rather than as it is. Clears when a listener comes back.\n */\n error?: unknown\n}\n\nconst SOURCE: CommentListSource<CommentsOptions, CommentThread[]> = {\n getState: getCommentThreadsState,\n getErrorState: getCommentsErrorState,\n resolve: resolveCommentThreads,\n getKey: getDocumentCommentsOptionsKey,\n parseKey: parseDocumentCommentsOptionsKey,\n}\n\n/**\n * Reads a document's comment threads and keeps them up to date.\n *\n * A thread carries its first comment plus its replies, and `status` and\n * `fieldPath` come from that first comment, so filtering by either selects\n * whole threads. Use {@link useComments} to read the same list flat, `scope` to\n * say which of the document's comments to cover — by default it follows the\n * perspective in view — and {@link useCommentsQuery} when the question is not\n * \"comments on this document\".\n *\n * Suspends until the comments have loaded. Switching document or filter is a\n * transition, so the previous list stays on screen and `isPending` goes true\n * rather than the component suspending again.\n *\n * @category Comments\n * @function\n * @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`\n * @returns The matching threads, and whether a switch is in flight\n *\n * @example Count the open threads on a field\n * ```tsx\n * function TitleCommentCount({documentId}: {documentId: string}) {\n * const {threads} = useCommentThreads({\n * documentId,\n * documentType: 'article',\n * fieldPath: 'title',\n * status: 'open',\n * })\n *\n * return <span>{threads.length}</span>\n * }\n * ```\n *\n * @beta\n */\nexport function useCommentThreads(\n options: WithResourceNameSupport<CommentsOptions>,\n): UseCommentThreadsResult {\n const {value, isPending, error} = useCommentList('useCommentThreads', options, SOURCE)\n return useMemo(() => ({threads: value, isPending, error}), [error, isPending, value])\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { a as DashboardTokenRefreshProvider, i as useOrganizationId, l as createStateSourceHook, n as useTopic, r as useEmit, s as useWindowConnection, t as useStudioWorkspacesByProjectIdDataset, u as useSanityInstance } from "../useStudioWorkspacesByProjectIdDataset-FRofq7KL.js";
1
+ import { t as useSanityInstance } from "../useSanityInstance-C0a_Ou_p.js";
2
+ import { a as DashboardTokenRefreshProvider, i as useOrganizationId, l as createStateSourceHook, n as useTopic, r as useEmit, s as useWindowConnection, t as useStudioWorkspacesByProjectIdDataset } from "../useStudioWorkspacesByProjectIdDataset-Cx-Q44d0.js";
2
3
  import { c } from "react-compiler-runtime";
3
4
  import "@sanity/sdk";
4
5
  import { createLogger, getApplicationOrigin, getWorkerClient, isMessageBusEnvironment, requireDashboardMessageBus } from "@sanity/sdk/_internal";