sanity 6.14.0 → 6.14.1

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 (163) hide show
  1. package/lib/{AddonDatasetProvider-0aiLWkZg.js → AddonDatasetProvider-C9tdum2G.js} +2 -2
  2. package/lib/{AddonDatasetProvider-0aiLWkZg.js.map → AddonDatasetProvider-C9tdum2G.js.map} +1 -1
  3. package/lib/{CalendarFilter-DVz369RP.js → CalendarFilter-C80uOkw-.js} +3 -3
  4. package/lib/{CalendarFilter-DVz369RP.js.map → CalendarFilter-C80uOkw-.js.map} +1 -1
  5. package/lib/{CommandList-CTDV_QZY.js → CommandList-duj-LVnd.js} +2 -2
  6. package/lib/{CommandList-CTDV_QZY.js.map → CommandList-duj-LVnd.js.map} +1 -1
  7. package/lib/{CommentInput-B5T1Iwnt.js → CommentInput-BXYQnGhq.js} +5 -5
  8. package/lib/{CommentInput-B5T1Iwnt.js.map → CommentInput-BXYQnGhq.js.map} +1 -1
  9. package/lib/{CommentsDocumentLayout-ByFwej_y.js → CommentsDocumentLayout-DAwAhx7q.js} +2 -2
  10. package/lib/{CommentsDocumentLayout-ByFwej_y.js.map → CommentsDocumentLayout-DAwAhx7q.js.map} +1 -1
  11. package/lib/{CommentsDocumentLayout-Czb6fC0_.js → CommentsDocumentLayout-pfM29WSy.js} +2 -2
  12. package/lib/{CommentsDocumentLayout-Czb6fC0_.js.map → CommentsDocumentLayout-pfM29WSy.js.map} +1 -1
  13. package/lib/{CommentsEnabledProvider-D2gutvsb.js → CommentsEnabledProvider-DN_oXwXM.js} +3 -3
  14. package/lib/{CommentsEnabledProvider-D2gutvsb.js.map → CommentsEnabledProvider-DN_oXwXM.js.map} +1 -1
  15. package/lib/{CommentsField-D2Fum0Jx.js → CommentsField-B7wTBRMB.js} +5 -5
  16. package/lib/{CommentsField-D2Fum0Jx.js.map → CommentsField-B7wTBRMB.js.map} +1 -1
  17. package/lib/{CommentsField-YM3cp3fA.js → CommentsField-BxoVuJOl.js} +4 -4
  18. package/lib/{CommentsField-YM3cp3fA.js.map → CommentsField-BxoVuJOl.js.map} +1 -1
  19. package/lib/{CommentsInput-Bx2t5AW_.js → CommentsInput-C3rEb5L8.js} +6 -6
  20. package/lib/{CommentsInput-Bx2t5AW_.js.map → CommentsInput-C3rEb5L8.js.map} +1 -1
  21. package/lib/{CommentsInput-BBBng3CJ.js → CommentsInput-CU-PFXmu.js} +7 -7
  22. package/lib/{CommentsInput-BBBng3CJ.js.map → CommentsInput-CU-PFXmu.js.map} +1 -1
  23. package/lib/{CommentsInspector-BnSG5Mq0.js → CommentsInspector-BJ1qwj6P.js} +6 -6
  24. package/lib/{CommentsInspector-BnSG5Mq0.js.map → CommentsInspector-BJ1qwj6P.js.map} +1 -1
  25. package/lib/{CommentsInspector-B5V_Bpz5.js → CommentsInspector-BQiMPjvm.js} +6 -6
  26. package/lib/{CommentsInspector-B5V_Bpz5.js.map → CommentsInspector-BQiMPjvm.js.map} +1 -1
  27. package/lib/{CommentsListItem-DnqAlN4p.js → CommentsListItem-QyYan1DB.js} +5 -5
  28. package/lib/{CommentsListItem-DnqAlN4p.js.map → CommentsListItem-QyYan1DB.js.map} +1 -1
  29. package/lib/{CommentsListItem-DVE4IMls.js → CommentsListItem-dvKmANi3.js} +4 -4
  30. package/lib/{CommentsListItem-DVE4IMls.js.map → CommentsListItem-dvKmANi3.js.map} +1 -1
  31. package/lib/{CommentsSelectedPathProvider-DRJ3Xqs4.js → CommentsSelectedPathProvider-COcPb3W3.js} +3 -3
  32. package/lib/{CommentsSelectedPathProvider-DRJ3Xqs4.js.map → CommentsSelectedPathProvider-COcPb3W3.js.map} +1 -1
  33. package/lib/{CommentsStudioLayout-Di510XhD.js → CommentsStudioLayout-BkX6o14w.js} +3 -3
  34. package/lib/{CommentsStudioLayout-Di510XhD.js.map → CommentsStudioLayout-BkX6o14w.js.map} +1 -1
  35. package/lib/{CommentsStudioLayout-Z09s50bM.js → CommentsStudioLayout-dIXEz52s.js} +3 -3
  36. package/lib/{CommentsStudioLayout-Z09s50bM.js.map → CommentsStudioLayout-dIXEz52s.js.map} +1 -1
  37. package/lib/{GlobalPerspectiveMenu-Cwur4_iD.js → GlobalPerspectiveMenu-0Hs276Z-.js} +15 -15
  38. package/lib/{GlobalPerspectiveMenu-Cwur4_iD.js.map → GlobalPerspectiveMenu-0Hs276Z-.js.map} +1 -1
  39. package/lib/{LoadingBlock-Ch_dBXfn.js → LoadingBlock-CElIdb7F.js} +3 -3
  40. package/lib/{LoadingBlock-Ch_dBXfn.js.map → LoadingBlock-CElIdb7F.js.map} +1 -1
  41. package/lib/{PerspectiveProvider-Yk7lgugx.js → PerspectiveProvider-D-6sweQH.js} +130 -97
  42. package/lib/PerspectiveProvider-D-6sweQH.js.map +1 -0
  43. package/lib/{ReleaseAvatar-C68bGuVQ.js → ReleaseAvatar-Bqp_Ci7r.js} +4 -4
  44. package/lib/{ReleaseAvatar-C68bGuVQ.js.map → ReleaseAvatar-Bqp_Ci7r.js.map} +1 -1
  45. package/lib/{ReleasesMetadataProvider-DabLuMD8.js → ReleasesMetadataProvider-BD6XRcpT.js} +2 -2
  46. package/lib/{ReleasesMetadataProvider-DabLuMD8.js.map → ReleasesMetadataProvider-BD6XRcpT.js.map} +1 -1
  47. package/lib/{ReleasesStudioLayout-DsygG30q.js → ReleasesStudioLayout-C6mmxoaY.js} +7 -7
  48. package/lib/{ReleasesStudioLayout-DsygG30q.js.map → ReleasesStudioLayout-C6mmxoaY.js.map} +1 -1
  49. package/lib/{ReleasesTool-CNXNODI_.js → ReleasesTool-DIDmkzic.js} +23 -23
  50. package/lib/{ReleasesTool-CNXNODI_.js.map → ReleasesTool-DIDmkzic.js.map} +1 -1
  51. package/lib/{SchedulePublishingStudioLayout-EsgEGZ7F.js → SchedulePublishingStudioLayout-DrZO-qbI.js} +3 -3
  52. package/lib/{SchedulePublishingStudioLayout-EsgEGZ7F.js.map → SchedulePublishingStudioLayout-DrZO-qbI.js.map} +1 -1
  53. package/lib/{SchedulePublishingUpsellProvider-CWxgqzFp.js → SchedulePublishingUpsellProvider-DeZ_jZIX.js} +2 -2
  54. package/lib/{SchedulePublishingUpsellProvider-CWxgqzFp.js.map → SchedulePublishingUpsellProvider-DeZ_jZIX.js.map} +1 -1
  55. package/lib/{ScheduledPublishingEnabledProvider-CQ-T1Y96.js → ScheduledPublishingEnabledProvider-B8C0_tc5.js} +3 -3
  56. package/lib/{ScheduledPublishingEnabledProvider-CQ-T1Y96.js.map → ScheduledPublishingEnabledProvider-B8C0_tc5.js.map} +1 -1
  57. package/lib/{SearchProvider-CEXmRg1N.js → SearchProvider-T8fsDJV5.js} +8 -8
  58. package/lib/{SearchProvider-CEXmRg1N.js.map → SearchProvider-T8fsDJV5.js.map} +1 -1
  59. package/lib/{SingleDocReleaseLayout-ByDXFS8N.js → SingleDocReleaseLayout-BpMXU9KY.js} +2 -2
  60. package/lib/{SingleDocReleaseLayout-ByDXFS8N.js.map → SingleDocReleaseLayout-BpMXU9KY.js.map} +1 -1
  61. package/lib/{SingleDocReleaseUpsellProvider-ByuDpBIG.js → SingleDocReleaseUpsellProvider-7_OXHySY.js} +3 -3
  62. package/lib/{SingleDocReleaseUpsellProvider-ByuDpBIG.js.map → SingleDocReleaseUpsellProvider-7_OXHySY.js.map} +1 -1
  63. package/lib/{TasksFooterOpenTasks-BSO8TgVF.js → TasksFooterOpenTasks-IFtOEGnB.js} +2 -2
  64. package/lib/{TasksFooterOpenTasks-BSO8TgVF.js.map → TasksFooterOpenTasks-IFtOEGnB.js.map} +1 -1
  65. package/lib/{TasksStudioActiveToolLayout-BXktrH08.js → TasksStudioActiveToolLayout-C99LQz4S.js} +20 -20
  66. package/lib/{TasksStudioActiveToolLayout-BXktrH08.js.map → TasksStudioActiveToolLayout-C99LQz4S.js.map} +1 -1
  67. package/lib/{TasksStudioLayout-BfN-M93c.js → TasksStudioLayout-CmFbUpnB.js} +4 -4
  68. package/lib/{TasksStudioLayout-BfN-M93c.js.map → TasksStudioLayout-CmFbUpnB.js.map} +1 -1
  69. package/lib/{TasksStudioNavbar-CfqloSfP.js → TasksStudioNavbar-DB7DJC4e.js} +2 -2
  70. package/lib/{TasksStudioNavbar-CfqloSfP.js.map → TasksStudioNavbar-DB7DJC4e.js.map} +1 -1
  71. package/lib/{TimeZoneButton-FCwCyJ1J.js → TimeZoneButton-B_ki5v8q.js} +7 -7
  72. package/lib/{TimeZoneButton-FCwCyJ1J.js.map → TimeZoneButton-B_ki5v8q.js.map} +1 -1
  73. package/lib/{Tool-PzN5dskE.js → Tool-DlkZrcrD.js} +15 -15
  74. package/lib/{Tool-PzN5dskE.js.map → Tool-DlkZrcrD.js.map} +1 -1
  75. package/lib/{UpsellPanel-T-5ZD_7k.js → UpsellPanel-ITWwjktp.js} +2 -2
  76. package/lib/{UpsellPanel-T-5ZD_7k.js.map → UpsellPanel-ITWwjktp.js.map} +1 -1
  77. package/lib/{VariantsStudioNavbar-D0XbvL1D.js → VariantsStudioNavbar-DwEV1roH.js} +9 -9
  78. package/lib/{VariantsStudioNavbar-D0XbvL1D.js.map → VariantsStudioNavbar-DwEV1roH.js.map} +1 -1
  79. package/lib/{VariantsTool-B3EEDrQT.js → VariantsTool-Dzhy3PST.js} +12 -12
  80. package/lib/{VariantsTool-B3EEDrQT.js.map → VariantsTool-Dzhy3PST.js.map} +1 -1
  81. package/lib/{WorkspaceLoader-BH_VDaY4.js → WorkspaceLoader-Ck4TMoR5.js} +31 -31
  82. package/lib/{WorkspaceLoader-BH_VDaY4.js.map → WorkspaceLoader-Ck4TMoR5.js.map} +1 -1
  83. package/lib/_createContext.js +1 -1
  84. package/lib/_unstable-embedded.js +5 -5
  85. package/lib/{buildRangeDecorationSelectionsFromComments-B1-tJPvG.js → buildRangeDecorationSelectionsFromComments-BnlhrvDK.js} +3 -3
  86. package/lib/{buildRangeDecorationSelectionsFromComments-B1-tJPvG.js.map → buildRangeDecorationSelectionsFromComments-BnlhrvDK.js.map} +1 -1
  87. package/lib/{buildTextSelectionFromFragment-BiLg851R.js → buildTextSelectionFromFragment-BXrYd9lr.js} +3 -3
  88. package/lib/{buildTextSelectionFromFragment-BiLg851R.js.map → buildTextSelectionFromFragment-BXrYd9lr.js.map} +1 -1
  89. package/lib/{constants-DdgHySkY.js → constants-BQItnHll.js} +2 -2
  90. package/lib/{constants-DdgHySkY.js.map → constants-BQItnHll.js.map} +1 -1
  91. package/lib/{datastores-D1tF4HQA.js → datastores-DNOJm1LF.js} +2 -2
  92. package/lib/{datastores-D1tF4HQA.js.map → datastores-DNOJm1LF.js.map} +1 -1
  93. package/lib/{i18n-Cl_y4bbR.js → i18n-JUYUb7y_.js} +2 -2
  94. package/lib/{i18n-Cl_y4bbR.js.map → i18n-JUYUb7y_.js.map} +1 -1
  95. package/lib/index.js +38 -38
  96. package/lib/{inputResolver-CUWPjdGU.js → inputResolver-Ce1lTBE-.js} +4 -4
  97. package/lib/{inputResolver-CUWPjdGU.js.map → inputResolver-Ce1lTBE-.js.map} +1 -1
  98. package/lib/{navigation.telemetry-rXclq03x.js → navigation.telemetry-BPxX2IEN.js} +10 -10
  99. package/lib/{navigation.telemetry-rXclq03x.js.map → navigation.telemetry-BPxX2IEN.js.map} +1 -1
  100. package/lib/{plugin-CSp8hwQE.js → plugin-Bvxhb5ko.js} +8 -8
  101. package/lib/{plugin-CSp8hwQE.js.map → plugin-Bvxhb5ko.js.map} +1 -1
  102. package/lib/{plugin-Daxe5hwG.js → plugin-Cv6TLYbE.js} +6 -6
  103. package/lib/{plugin-Daxe5hwG.js.map → plugin-Cv6TLYbE.js.map} +1 -1
  104. package/lib/{plugin-BFTpdKKH.js → plugin-D6-7jrXf.js} +3 -3
  105. package/lib/{plugin-BFTpdKKH.js.map → plugin-D6-7jrXf.js.map} +1 -1
  106. package/lib/{plugin-dtgDcBsL.js → plugin-D_GVPwTR.js} +6 -6
  107. package/lib/{plugin-dtgDcBsL.js.map → plugin-D_GVPwTR.js.map} +1 -1
  108. package/lib/{releases.telemetry-B6tRA9U2.js → releases.telemetry-BAO7xaO7.js} +6 -6
  109. package/lib/{releases.telemetry-B6tRA9U2.js.map → releases.telemetry-BAO7xaO7.js.map} +1 -1
  110. package/lib/{resources-BjljYbUa.js → resources-Bw1bpPhG.js} +2 -2
  111. package/lib/{resources-BjljYbUa.js.map → resources-Bw1bpPhG.js.map} +1 -1
  112. package/lib/{resources-DYxnNjS8.js → resources-CC1qBsSO.js} +2 -2
  113. package/lib/{resources-DYxnNjS8.js.map → resources-CC1qBsSO.js.map} +1 -1
  114. package/lib/{resources-D7Mp6N-8.js → resources-CH42UqhC.js} +2 -2
  115. package/lib/{resources-D7Mp6N-8.js.map → resources-CH42UqhC.js.map} +1 -1
  116. package/lib/{resources-GpX0LblP.js → resources-Cq1lXH8T.js} +2 -2
  117. package/lib/{resources-GpX0LblP.js.map → resources-Cq1lXH8T.js.map} +1 -1
  118. package/lib/{resources-B7mfG9Km.js → resources-D7XsFe7y.js} +2 -2
  119. package/lib/{resources-B7mfG9Km.js.map → resources-D7XsFe7y.js.map} +1 -1
  120. package/lib/{resources-CmmAynkL.js → resources-DYn0yzEW.js} +2 -2
  121. package/lib/{resources-CmmAynkL.js.map → resources-DYn0yzEW.js.map} +1 -1
  122. package/lib/{resources-C79qQva3.js → resources-TsgtFPi7.js} +2 -2
  123. package/lib/{resources-C79qQva3.js.map → resources-TsgtFPi7.js.map} +1 -1
  124. package/lib/{scheduleItem-Bdvl81Kb.js → scheduleItem-5fXCZgfo.js} +13 -13
  125. package/lib/{scheduleItem-Bdvl81Kb.js.map → scheduleItem-5fXCZgfo.js.map} +1 -1
  126. package/lib/{schedules-D7bPbTPm.js → schedules-BsE0_g47.js} +3 -3
  127. package/lib/{schedules-D7bPbTPm.js.map → schedules-BsE0_g47.js.map} +1 -1
  128. package/lib/{searchDocumentRelease-v1o9dMnE.js → searchDocumentRelease-Bang3A8l.js} +5 -5
  129. package/lib/{searchDocumentRelease-v1o9dMnE.js.map → searchDocumentRelease-Bang3A8l.js.map} +1 -1
  130. package/lib/{studioClient-EJDu6kOb.js → studioClient-C7B6Aobi.js} +2 -2
  131. package/lib/{studioClient-EJDu6kOb.js.map → studioClient-C7B6Aobi.js.map} +1 -1
  132. package/lib/{useActiveReleases-Bh_Q6f7G.js → useActiveReleases-DxYjyTB1.js} +5 -5
  133. package/lib/{useActiveReleases-Bh_Q6f7G.js.map → useActiveReleases-DxYjyTB1.js.map} +1 -1
  134. package/lib/{useBundleDocuments-zP6JiTzz.js → useBundleDocuments-2YaaN-2l.js} +3 -3
  135. package/lib/{useBundleDocuments-zP6JiTzz.js.map → useBundleDocuments-2YaaN-2l.js.map} +1 -1
  136. package/lib/{useComments-BGOJwUe0.js → useComments-DWh1k0kS.js} +5 -5
  137. package/lib/{useComments-BGOJwUe0.js.map → useComments-DWh1k0kS.js.map} +1 -1
  138. package/lib/{useCommentsTelemetry-BMkf6MTO.js → useCommentsTelemetry-BbJ8lTKN.js} +4 -4
  139. package/lib/{useCommentsTelemetry-BMkf6MTO.js.map → useCommentsTelemetry-BbJ8lTKN.js.map} +1 -1
  140. package/lib/{useDocumentPreviewValues-CryTvfKc.js → useDocumentPreviewValues-CK5VteK3.js} +4 -4
  141. package/lib/{useDocumentPreviewValues-CryTvfKc.js.map → useDocumentPreviewValues-CK5VteK3.js.map} +1 -1
  142. package/lib/{useFieldActions-BTj7VsW5.js → useFieldActions-BmY1Kh3s.js} +2 -2
  143. package/lib/{useFieldActions-BTj7VsW5.js.map → useFieldActions-BmY1Kh3s.js.map} +1 -1
  144. package/lib/{useProjectId-BN6GCdwS.js → useProjectId-C8pZxybz.js} +2 -2
  145. package/lib/{useProjectId-BN6GCdwS.js.map → useProjectId-C8pZxybz.js.map} +1 -1
  146. package/lib/{useReleasesToolAvailable-CQ9-I8Tt.js → useReleasesToolAvailable-DjaSujLo.js} +3 -3
  147. package/lib/{useReleasesToolAvailable-CQ9-I8Tt.js.map → useReleasesToolAvailable-DjaSujLo.js.map} +1 -1
  148. package/lib/{useScheduledDraftMenuActions-OSkdxONo.js → useScheduledDraftMenuActions-DSJU6xQa.js} +9 -9
  149. package/lib/{useScheduledDraftMenuActions-OSkdxONo.js.map → useScheduledDraftMenuActions-DSJU6xQa.js.map} +1 -1
  150. package/lib/{useStudioUrl-DUBI_S4K.js → useStudioUrl-DcTGV00c.js} +5 -5
  151. package/lib/{useStudioUrl-DUBI_S4K.js.map → useStudioUrl-DcTGV00c.js.map} +1 -1
  152. package/lib/{useTasksNavigation-fohCXW6l.js → useTasksNavigation-tAXFJd2V.js} +2 -2
  153. package/lib/{useTasksNavigation-fohCXW6l.js.map → useTasksNavigation-tAXFJd2V.js.map} +1 -1
  154. package/lib/{useTimeZone-DM8ZmUO2.js → useTimeZone-Dj7C8tfZ.js} +2 -2
  155. package/lib/{useTimeZone-DM8ZmUO2.js.map → useTimeZone-Dj7C8tfZ.js.map} +1 -1
  156. package/lib/{utils-D-4rueJZ.js → utils-CT034e4q.js} +3 -3
  157. package/lib/{utils-D-4rueJZ.js.map → utils-CT034e4q.js.map} +1 -1
  158. package/lib/{validationUtils-jTd1rxfY.js → validationUtils-BZPoHEYN.js} +4 -4
  159. package/lib/{validationUtils-jTd1rxfY.js.map → validationUtils-BZPoHEYN.js.map} +1 -1
  160. package/lib/{version-D0Vx4cX1.js → version-BDSMcNU7.js} +2 -2
  161. package/lib/{version-D0Vx4cX1.js.map → version-BDSMcNU7.js.map} +1 -1
  162. package/package.json +17 -17
  163. package/lib/PerspectiveProvider-Yk7lgugx.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"datastores-D1tF4HQA.js","names":["scan","switchMap","tap","{children}: ResourceCacheProviderProps","(): ResourceCache => {\n const namespaces = new Map<string, MultiKeyWeakMap>()\n\n // this is used to replace the `null` values in any `dependencies` so that\n // they can be used in the `MultiKeyWeakMap` which doesn't accept null\n const nullReplacer = {}\n // this is used to replace `[]` dependencies to maintain the\n // same referential integrity in the weak map lookup\n const emptyDependenciesReplacer = [nullReplacer]\n\n const removeNullDependencies = (dependencies: (object | null)[]) =>\n dependencies.length\n ? dependencies.map((dep) => (dep === null ? nullReplacer : dep))\n : emptyDependenciesReplacer\n\n return {\n get: ({namespace, dependencies}) => {\n const dependenciesWithoutNull = removeNullDependencies(dependencies)\n const namespaceMap = namespaces.get(namespace)\n return namespaceMap?.get(dependenciesWithoutNull)\n },\n\n set: ({namespace, dependencies, value}) => {\n const namespaceMap = namespaces.get(namespace) || createMultiKeyWeakMap()\n const dependenciesWithoutNull = removeNullDependencies(dependencies)\n namespaces.set(namespace, namespaceMap)\n namespaceMap.set(dependenciesWithoutNull, value)\n },\n }\n }","<ResourceCacheContext.Provider value={resourceCache}>{children}</ResourceCacheContext.Provider>","ResourceCacheContext.Provider","{namespace, dependencies}","dependencies","{namespace, dependencies, value}","namespaceMap","namespace","dependenciesWithoutNull","getClient(DEFAULT_STUDIO_CLIENT_OPTIONS)","useMemo(() => {\n const userStore =\n resourceCache.get<UserStore>({\n namespace: 'userStore',\n dependencies: [client, currentUser],\n }) || createUserStore({client, currentUser})\n\n resourceCache.set({\n namespace: 'userStore',\n dependencies: [client, currentUser],\n value: userStore,\n })\n\n return userStore\n }, [client, currentUser, resourceCache])","useMemo(() => {\n const grantsStore =\n resourceCache.get<GrantsStore>({\n namespace: 'grantsStore',\n dependencies: [client, currentUser, errorHandler],\n }) || createGrantsStore({client, userId: currentUser?.id || null, errorHandler})\n\n resourceCache.set({\n namespace: 'grantsStore',\n dependencies: [client, currentUser, errorHandler],\n value: grantsStore,\n })\n\n return grantsStore\n }, [client, currentUser, errorHandler, resourceCache])","useMemo(() => {\n const historyStore =\n resourceCache.get<HistoryStore>({\n namespace: 'historyStore',\n dependencies: [client],\n }) || createHistoryStore({client})\n\n resourceCache.set({\n namespace: 'historyStore',\n dependencies: [client],\n value: historyStore,\n })\n\n return historyStore\n }, [client, resourceCache])","useMemo(() => {\n const documentPreviewStore =\n resourceCache.get<DocumentPreviewStore>({\n namespace: 'documentPreviewStore',\n dependencies: [client],\n }) || createDocumentPreviewStore({client})\n\n resourceCache.set({\n namespace: 'documentPreviewStore',\n dependencies: [client],\n value: documentPreviewStore,\n })\n\n return documentPreviewStore\n }, [client, resourceCache])","(error: OutOfSyncError) => {\n telemetry.log(DocumentDesynced, {errorName: error.name})\n }","useCallback(\n (error: OutOfSyncError) => {\n telemetry.log(DocumentDesynced, {errorName: error.name})\n },\n [telemetry],\n )","(event: LatencyReportEvent) => {\n if (event.latencyMs > IGNORE_LATENCY_BELOW_MS) {\n telemetry.log(HighListenerLatencyOccurred, {\n latency: event.latencyMs,\n shard: event.shard,\n transactionId: event.transactionId,\n })\n }\n }","useCallback(\n (event: LatencyReportEvent) => {\n if (event.latencyMs > IGNORE_LATENCY_BELOW_MS) {\n telemetry.log(HighListenerLatencyOccurred, {\n latency: event.latencyMs,\n shard: event.shard,\n transactionId: event.transactionId,\n })\n }\n },\n [telemetry],\n )","() => {\n const now = Date.now()\n if (now - slowCommitCooldown.lastToastAt < SLOW_COMMIT_TOAST_COOLDOWN_MS) return\n slowCommitCooldown.lastToastAt = now\n toast.push({\n title: t('document-store.slow-commit.title'),\n description: t('document-store.slow-commit.description'),\n status: 'warning',\n })\n }","useCallback(() => {\n const now = Date.now()\n if (now - slowCommitCooldown.lastToastAt < SLOW_COMMIT_TOAST_COOLDOWN_MS) return\n slowCommitCooldown.lastToastAt = now\n toast.push({\n title: t('document-store.slow-commit.title'),\n description: t('document-store.slow-commit.description'),\n status: 'warning',\n })\n }, [toast, t])","(event: DocumentPairLoadedEvent) => {\n telemetry.log(DocumentPairLoadingMeasured, {\n durationMs: event.durationMs,\n fromCache: event.fromCache,\n hasPublished: event.hasPublished,\n hasDraft: event.hasDraft,\n hasVersion: event.hasVersion,\n })\n }","event","useCallback(\n (event: DocumentPairLoadedEvent) => {\n telemetry.log(DocumentPairLoadingMeasured, {\n durationMs: event.durationMs,\n fromCache: event.fromCache,\n hasPublished: event.hasPublished,\n hasDraft: event.hasDraft,\n hasVersion: event.hasVersion,\n })\n },\n [telemetry],\n )","(event: MutationPerformanceEvent) => {\n telemetry.log(MutationPerformanceMeasured, event)\n }","useCallback(\n (event: MutationPerformanceEvent) => {\n telemetry.log(MutationPerformanceMeasured, event)\n },\n [telemetry],\n )","(event: DocumentRebaseTelemetryEvent) => {\n telemetry.log(DocumentRebaseOccurred, event)\n }","useCallback(\n (event: DocumentRebaseTelemetryEvent) => {\n telemetry.log(DocumentRebaseOccurred, event)\n },\n [telemetry],\n )","useMemo(() => {\n const documentStore =\n resourceCache.get<DocumentStore>({\n namespace: 'documentStore',\n dependencies: [\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n errorHandler,\n ],\n }) ||\n createDocumentStore({\n getClient,\n documentPreviewStore,\n historyStore,\n initialValueTemplates: templates,\n schema,\n i18n,\n currentUser,\n extraOptions: {\n onReportLatency: handleReportLatency,\n onSyncErrorRecovery: handleSyncErrorRecovery,\n onSlowCommit: handleSlowCommit,\n onDocumentPairLoaded: handleDocumentPairLoaded,\n onReportMutationPerformance: handleReportMutationPerformance,\n onDocumentRebase: handleDocumentRebase,\n snapshotFetchErrorHandler: errorHandler,\n },\n })\n\n resourceCache.set({\n namespace: 'documentStore',\n dependencies: [\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n errorHandler,\n ],\n value: documentStore,\n })\n\n return documentStore\n }, [\n resourceCache,\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n templates,\n handleReportLatency,\n handleSyncErrorRecovery,\n handleSlowCommit,\n handleDocumentPairLoaded,\n handleReportMutationPerformance,\n handleDocumentRebase,\n errorHandler,\n ])","useMemo(() => {\n const connectionStatusStore =\n resourceCache.get<ConnectionStatusStore>({\n namespace: 'connectionStatusStore',\n dependencies: [bifur],\n }) || createConnectionStatusStore({bifur})\n\n resourceCache.set({\n namespace: 'connectionStatusStore',\n dependencies: [bifur],\n value: connectionStatusStore,\n })\n\n return connectionStatusStore\n }, [bifur, resourceCache])","{bifur}","useMemo(() => {\n const presenceStore =\n resourceCache.get<PresenceStore>({\n namespace: 'presenceStore',\n dependencies: [bifur, connectionStatusStore, userStore],\n }) || createPresenceStore({bifur, connectionStatusStore, userStore})\n\n resourceCache.set({\n namespace: 'presenceStore',\n dependencies: [bifur, connectionStatusStore, userStore],\n value: presenceStore,\n })\n\n return presenceStore\n }, [bifur, connectionStatusStore, resourceCache, userStore])","useMemo(() => {\n const projectStore =\n resourceCache.get<ProjectStore>({\n namespace: 'projectStore',\n dependencies: [client],\n }) || createProjectStore({client})\n\n resourceCache.set({\n namespace: 'projectStore',\n dependencies: [client],\n value: projectStore,\n })\n\n return projectStore\n }, [client, resourceCache])","useMemo(() => {\n const cacheKey = getKeyValueStoreCacheKey(client)\n const cached = keyValueStoreCache.get(cacheKey)\n if (cached) return cached\n\n const keyValueStore = createKeyValueStore({client})\n keyValueStoreCache.set(cacheKey, keyValueStore)\n return keyValueStore\n }, [client])","useMemo(() => {\n const renderingContextStore =\n resourceCache.get<RenderingContextStore>({\n dependencies: [],\n namespace: 'RenderingContextStore',\n }) || createRenderingContextStore()\n\n resourceCache.set({\n dependencies: [],\n namespace: 'RenderingContextStore',\n value: renderingContextStore,\n })\n\n return renderingContextStore\n }, [resourceCache])","() => renderingContext.getCapabilities() ?? EMPTY_CAPABILITIES","useMemo(() => {\n const store =\n resourceCache.get<ComlinkStore>({\n dependencies: [capabilities],\n namespace: 'ComlinkStore',\n }) || createComlinkStore({capabilities})\n\n resourceCache.set({\n dependencies: [capabilities],\n namespace: 'ComlinkStore',\n value: store,\n })\n\n return store\n }, [capabilities, resourceCache])","() => {\n comlinkStore.start()\n }","[comlinkStore]"],"sources":["../src/core/util/isRecord.ts","../src/core/util/postTask.ts","../src/core/templates/util/isRecord.ts","../src/core/templates/util/deepAssign.ts","../src/core/templates/validate.ts","../src/core/templates/resolve.ts","../src/core/hooks/useSchema.ts","../src/core/util/apiErrors.ts","../src/core/studio/requestErrors/classify.ts","../src/core/studio/requestErrors/createRequestErrorChannel.ts","../src/core/studio/requestErrors/useStudioErrorHandler.ts","../src/core/hooks/useTemplates.ts","../src/core/util/const.ts","../src/core/util/rxSwr.ts","../src/core/util/shallowEquals.ts","../src/core/preview/constants.tsx","../src/core/preview/utils/debounceCollect.ts","../src/core/preview/availability.ts","../src/core/preview/utils/shareReplayLatest.ts","../src/core/preview/createGlobalListener.ts","../src/core/preview/utils/applyMendozaPatch.ts","../src/core/preview/createObserveDocument.ts","../src/core/preview/utils/keysOf.ts","../src/core/preview/utils/props.ts","../src/core/preview/createPathObserver.ts","../src/core/preview/utils/getPreviewPaths.ts","../src/core/preview/utils/portableText.ts","../src/core/preview/utils/prepareForPreview.ts","../src/core/preview/createPreviewObserver.ts","../src/core/preview/documentPair.ts","../src/core/preview/liveDocumentIdSet.ts","../src/core/releases/util/releasesClient.ts","../src/core/variants/util/variantApiVersion.ts","../src/core/preview/utils/hasEqualFields.ts","../src/core/preview/utils/isUniqueBy.ts","../src/core/util/searchUtils.ts","../src/core/preview/utils/optimizeQuery.ts","../src/core/preview/observeFields.ts","../src/core/preview/observeVersionDocumentIds.ts","../src/core/preview/documentPreviewStore.ts","../src/core/store/comlink/createComlinkStore.ts","../src/core/util/catchWithCount.ts","../src/core/store/connection-status/connection-status-store.ts","../src/core/store/document/__telemetry__/documentOutOfSyncEvents.telemetry.ts","../src/core/store/document/__telemetry__/documentPairLoading.telemetry.ts","../src/core/store/document/__telemetry__/documentRebase.telemetry.ts","../src/core/store/document/__telemetry__/listenerLatency.telemetry.ts","../src/core/store/document/__telemetry__/mutationPerformance.telemetry.ts","../src/core/util/getDocumentVariantType.ts","../src/core/variants/tool/util.ts","../src/core/store/document/buffered-doc/createObservableBufferedDocument.ts","../src/core/store/document/buffered-doc/createBufferedDocument.ts","../src/core/store/document/debug.ts","../src/core/store/document/utils/dedupeListenerEvents.ts","../src/core/store/document/utils/eventChainUtils.ts","../src/core/store/document/utils/sequentializeListenerEvents.ts","../src/core/store/document/getPairListener.ts","../src/core/store/document/document-pair/utils/actionsApiClient.ts","../src/core/store/document/document-pair/utils/operationsApiClient.ts","../src/core/store/document/document-pair/checkoutPair.ts","../src/core/store/document/utils/createMemoizer.ts","../src/core/store/document/utils/memoKey.ts","../src/core/store/document/document-pair/memoizeKeyGen.ts","../src/core/store/document/document-pair/memoizedPair.ts","../src/core/store/document/document-pair/commitErrorStatus.ts","../src/core/store/document/document-pair/consistencyStatus.ts","../src/core/store/document/document-pair/documentEvents.ts","../src/core/store/document/document-pair/snapshotPair.ts","../src/core/store/document/document-pair/operationArgs.ts","../src/core/store/document/document-pair/getOperationStoreKey.ts","../src/core/store/document/document-pair/operations/commit.ts","../src/core/store/document/document-pair/utils/assertNotVariantVersion.ts","../src/core/store/document/document-pair/utils/isLiveEditEnabled.ts","../src/core/store/document/document-pair/operations/delete.ts","../src/core/store/document/document-pair/operations/discardChanges.ts","../src/core/variants/documents/getVariantVersionInfo.ts","../src/core/store/document/document-pair/operations/duplicate.ts","../src/core/store/document/document-pair/operations/patch.ts","../src/core/store/document/document-pair/operations/publish.ts","../src/core/store/document/document-pair/operations/restore.ts","../src/core/store/document/document-pair/operations/unpublish.ts","../src/core/store/document/document-pair/serverOperations/delete.ts","../src/core/store/document/document-pair/serverOperations/discardChanges.ts","../src/core/store/document/document-pair/serverOperations/patch.ts","../src/core/store/document/document-pair/serverOperations/publish.ts","../src/core/store/document/document-pair/serverOperations/restore.ts","../src/core/releases/util/isGoingToUnpublish.ts","../src/core/store/document/document-pair/serverOperations/unpublish.ts","../src/core/store/document/document-pair/operationEvents.ts","../src/core/store/document/document-pair/operations/helpers.ts","../src/core/store/document/document-pair/editOperations.ts","../src/core/releases/store/constants.ts","../src/core/releases/util/getReleaseIdFromReleaseDocumentId.ts","../src/core/util/measureFirstEmission.ts","../src/core/store/document/document-pair/editState.ts","../src/core/validation/validateDocumentWithReferences.ts","../src/core/validation/index.ts","../src/core/store/document/document-pair/validation.ts","../src/core/store/document/initialValue/initialValue.ts","../src/core/store/document/listenQuery.ts","../src/core/store/document/normalizeDocumentPairTarget.ts","../src/core/store/document/resolveTypeForDocument.ts","../src/core/store/document/document-store.ts","../../../node_modules/.pnpm/rxjs-etc@10.6.2_rxjs@7.8.2/node_modules/rxjs-etc/dist/esm/operators/refCountDelay.js","../src/core/store/debugParams/debugParams.ts","../src/core/store/grants/debug/exampleGrants.ts","../src/core/store/grants/debug/roleGrants.ts","../src/core/store/grants/grantsStore.ts","../src/core/environment/index.ts","../src/core/store/history/history/chunker.ts","../src/core/store/events/diffValue.ts","../src/core/store/history/history/diffValue.ts","../src/core/store/history/history/TwoEndedArray.ts","../src/core/store/history/history/utils.ts","../src/core/store/history/history/Timeline.ts","../src/core/store/events/getJsonStream.ts","../src/core/store/history/history/Aligner.ts","../src/core/store/history/history/Reconstruction.ts","../src/core/store/history/history/TimelineController.ts","../src/core/store/history/createHistoryStore.ts","../src/core/util/supportsLocalStorage.ts","../src/core/store/key-value/storage/memoryStorage.ts","../src/core/store/key-value/storage/localStoreStorage.ts","../src/core/store/key-value/localStorageSWR.ts","../src/core/store/key-value/storage/serverStorage.ts","../src/core/store/key-value/serverKeyValueStore.ts","../src/core/store/key-value/keyValueStore.ts","../src/core/store/presence/message-transports/bifurTransport.ts","../src/core/store/presence/mock-events.ts","../src/core/store/presence/presence-store.ts","../src/core/store/project/projectStore.ts","../src/core/store/renderingContext/types.ts","../src/core/store/renderingContext/coreUiRenderingContext.ts","../src/core/store/renderingContext/defaultRenderingContext.ts","../src/core/store/renderingContext/listCapabilities.ts","../src/core/store/renderingContext/createRenderingContextStore.ts","../src/core/store/createMultiKeyWeakMap.ts","../src/core/store/ResourceCacheProvider.tsx","../src/core/store/user/userStore.ts","../src/core/store/datastores.ts"],"sourcesContent":["/**\n * @internal\n */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n","/**\n * Schedule the provided callback using `scheduler.postTask`, if it's available.\n * Otherwise, call it immediately.\n */\nexport function postTask<Result>(\n callback: () => Result,\n options: PostTaskOptions = {},\n): Result | Promise<Result> {\n if ('scheduler' in window && typeof window.scheduler?.postTask === 'function') {\n return window.scheduler.postTask(callback, options)\n }\n return callback()\n}\n","import isPlainObject from 'lodash-es/isPlainObject.js'\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return isPlainObject(value)\n}\n","import {isRecord} from './isRecord'\n\n// deep object assign for objects\n// note: doesn't mutate target\nexport default function deepAssign(\n target: Record<string, unknown>,\n source: Record<string, unknown>,\n): Record<string, unknown> {\n const result = {...target, ...source}\n\n Object.keys(result).forEach((key) => {\n const sourceVal = source[key]\n const targetVal = target[key]\n if (isRecord(sourceVal) && isRecord(targetVal)) {\n result[key] = deepAssign(targetVal, sourceVal)\n }\n })\n return result\n}\n","import {type Schema} from '@sanity/types'\nimport {randomKey} from '@sanity/util/content'\nimport {toString as pathToString} from '@sanity/util/paths'\n\nimport {type Template, type TemplateParameter} from './types'\nimport {isRecord} from './util/isRecord'\n\nconst ALLOWED_REF_PROPS = [\n '_dataset',\n '_projectId',\n '_strengthenOnPublish',\n '_key',\n '_ref',\n '_type',\n '_weak',\n]\nconst REQUIRED_TEMPLATE_PROPS: (keyof Template)[] = ['id', 'title', 'schemaType', 'value']\n\nfunction templateId(template: Template, i: number) {\n return quote(template.id || template.title) || (typeof i === 'number' && `at index ${i}`) || ''\n}\n\nfunction quote(str: string) {\n return str && str.length > 0 ? `\"${str}\"` : str\n}\n\nexport function validateTemplates(schema: Schema, templates: Template[]): Template[] {\n const idMap = new Map()\n\n templates.forEach((template, i) => {\n const id = templateId(template, i)\n\n if (typeof (template as {[key: string]: any}).values !== 'undefined' && !template.value) {\n throw new Error(`Template ${id} is missing \"value\" property, but contained \"values\". Typo?`)\n }\n\n const missing = REQUIRED_TEMPLATE_PROPS.filter((prop) => !template[prop])\n if (missing.length > 0) {\n throw new Error(`Template ${id} is missing required properties: ${missing.join(', ')}`)\n }\n\n if (typeof template.value !== 'function' && !isRecord(template.value)) {\n throw new Error(\n `Template ${id} has an invalid \"value\" property; should be a function or an object`,\n )\n }\n\n if (typeof template.parameters !== 'undefined') {\n if (Array.isArray(template.parameters)) {\n template.parameters.forEach((param, j) => validateParameter(schema, param, template, j))\n } else {\n throw new Error(`Template ${id} has an invalid \"parameters\" property; must be an array`)\n }\n }\n\n if (idMap.has(template.id)) {\n const dupeIndex = idMap.get(template.id)\n const dupe = `${quote(templates[dupeIndex].title)} at index ${dupeIndex}`\n throw new Error(\n `Template \"${template.title}\" at index ${i} has the same ID (\"${template.id}\") as template ${dupe}`,\n )\n }\n\n idMap.set(template.id, i)\n })\n\n return templates\n}\n\nexport function validateInitialObjectValue<T extends Record<string, unknown>>(\n value: T,\n template: Template,\n): T {\n const contextError = (msg: string) => `Template \"${template.id}\" initial value: ${msg}`\n\n if (!isRecord(value)) {\n throw new Error(contextError(`resolved to a non-object`))\n }\n\n if (value._type && template.schemaType !== value._type) {\n throw new Error(\n contextError(\n `includes \"_type\"-property (${value._type}) that does not match template (${template.schemaType})`,\n ),\n )\n }\n\n try {\n return validateValue(value)\n } catch (err) {\n err.message = contextError(err.message)\n throw err\n }\n}\n\nfunction validateValue(value: unknown, path: (string | number)[] = [], parentIsArray = false): any {\n if (Array.isArray(value)) {\n return value.map((item, i) => {\n if (Array.isArray(item)) {\n throw new Error(\n `multidimensional arrays are not supported (at path \"${pathToString(path)}\")`,\n )\n }\n\n return validateValue(item, path.concat(i), true)\n })\n }\n\n if (!isRecord(value)) {\n return value\n }\n\n // Apply missing keys is the parent is an array\n const initial: {[key: string]: any} = parentIsArray && !value._key ? {_key: randomKey()} : {}\n\n // Ensure non-root objects have _type\n if (path.length > 0 && !value._type) {\n if (value._ref) {\n // In the case of references, we know what the type should be, so apply it\n initial._type = 'reference'\n } else {\n // todo: consider if we need to re-instantiate this. It currently makes the valid case of having an initial object value for a field fail\n // throw new Error(`missing \"_type\" property at path \"${pathToString(path)}\"`)\n }\n }\n\n if (value._ref) {\n validateReference(value, path)\n }\n\n // Validate deeply\n return Object.keys(value).reduce((acc, key) => {\n acc[key] = validateValue(value[key], path.concat([key]))\n return acc\n }, initial)\n}\n\nfunction validateParameter(\n schema: Schema,\n parameter: TemplateParameter,\n template: Template,\n index: number,\n) {\n // const schema = getDefaultSchema()\n\n if (!parameter.name) {\n throw new Error(\n `Template ${template.id} has a parameter at index ${index} that is missing its \"name\"-property`,\n )\n }\n\n // I know, this is a weird one\n if (parameter.name === 'template') {\n throw new Error(\n `Template parameters cannot be named \"template\", see parameter #${index} for template ${template.id}`,\n )\n }\n\n if (!schema.get(parameter.type)) {\n throw new Error(\n `Template parameter \"${parameter.name}\" has an invalid/unknown type: \"${parameter.type}\"`,\n )\n }\n}\n\nfunction validateReference(\n value: {_type?: unknown; type?: unknown},\n path: (string | number)[] = [],\n) {\n if (!value._type && value.type) {\n throw new Error(\n `Reference is missing \"_type\", but has a \"type\" property at path \"${pathToString(path)}\"`,\n )\n }\n\n const disallowed = Object.keys(value).filter((key) => !ALLOWED_REF_PROPS.includes(key))\n if (disallowed.length > 0) {\n const plural = disallowed.length > 1 ? 'properties' : 'property'\n throw new Error(\n `Disallowed ${plural} found in reference: ${disallowed\n .map(quote)\n .join(', ')} at path \"${pathToString(path)}\"`,\n )\n }\n}\n","import {\n type ArraySchemaType,\n type InitialValueProperty,\n type InitialValueResolver,\n type InitialValueResolverContext,\n isArraySchemaType,\n isObjectSchemaType,\n type ObjectSchemaType,\n type Schema,\n type SchemaType,\n} from '@sanity/types'\nimport {isDeepEmpty, randomKey, resolveTypeName} from '@sanity/util/content'\n\nimport {postTask} from '../util/postTask'\nimport {type Template} from './types'\nimport deepAssign from './util/deepAssign'\nimport {isRecord} from './util/isRecord'\nimport {validateInitialObjectValue} from './validate'\n\n/** @internal */\nexport type Serializeable<T> = {\n serialize(): T\n}\n\ninterface Options {\n useCache?: boolean\n}\n\n/** @internal */\nexport function isBuilder(template: unknown): template is Serializeable<Template> {\n return isRecord(template) && typeof template.serialize === 'function'\n}\n\nconst cache = new WeakMap<\n InitialValueResolver<unknown, unknown>,\n Record<string, unknown | Promise<unknown>>\n>()\n\n/** @internal */\n// returns the \"resolved\" value from an initial value property (e.g. type.initialValue)\nexport async function resolveValue<Params, InitialValue>(\n initialValueOpt: InitialValueProperty<Params, InitialValue>,\n params: Params | undefined,\n context: InitialValueResolverContext,\n options?: Options,\n): Promise<InitialValue | undefined> {\n const useCache = options?.useCache\n\n if (typeof initialValueOpt === 'function') {\n const cached = cache.get(initialValueOpt as InitialValueResolver<unknown, unknown>)\n\n const key = JSON.stringify([\n params,\n context.projectId,\n context.dataset,\n context.currentUser?.id,\n ])\n\n if (useCache && cached?.[key]) {\n return cached[key] as InitialValue | Promise<InitialValue>\n }\n\n const value = (initialValueOpt as InitialValueResolver<Params, InitialValue>)(params, context)\n\n if (useCache) {\n cache.set(initialValueOpt as InitialValueResolver<unknown, unknown>, {\n ...cached,\n [key]: value,\n })\n }\n\n return value\n }\n\n return initialValueOpt\n}\n\n/** @internal */\nexport async function resolveInitialValue(\n schema: Schema,\n template: Template,\n params: {[key: string]: any} = {},\n context: InitialValueResolverContext,\n options?: Options,\n): Promise<{[key: string]: any}> {\n // Template builder?\n if (isBuilder(template)) {\n return resolveInitialValue(schema, template.serialize(), params, context, options)\n }\n\n const {id, schemaType: schemaTypeName, value} = template\n if (!value) {\n throw new Error(`Template \"${id}\" has invalid \"value\" property`)\n }\n\n let resolvedValue = await resolveValue(value, params, context, options)\n\n if (!isRecord(resolvedValue)) {\n throw new Error(\n `Template \"${id}\" has invalid \"value\" property - must be a plain object or a resolver function returning a plain object`,\n )\n }\n\n // Ensure _type is set on empty objects\n if (isRecord(resolvedValue) && !Object.keys(resolvedValue).length) {\n resolvedValue = {_type: schemaTypeName}\n }\n\n // validate default document initial values\n resolvedValue = validateInitialObjectValue(resolvedValue, template)\n\n // Get deep initial values from schema types (note: the initial value from template overrides the types)\n const schemaType = schema.get(schemaTypeName)\n if (!schemaType) {\n throw new Error(`Could not find schema type with name \"${schemaTypeName}\".`)\n }\n\n const newValue = deepAssign(\n (await resolveInitialValueForType(\n schemaType,\n params,\n DEFAULT_MAX_RECURSION_DEPTH,\n context,\n options,\n )) || {},\n resolvedValue as Record<string, unknown>,\n )\n\n // revalidate and return new initial values\n // todo: would be better to do validation as part of type resolution\n return validateInitialObjectValue(newValue, template)\n}\n\n/** @internal */\nfunction getItemType(arrayType: ArraySchemaType, item: unknown): SchemaType | undefined {\n const itemTypeName = resolveTypeName(item)\n\n return itemTypeName === 'object' && arrayType.of.length === 1\n ? arrayType.of[0]\n : arrayType.of.find((memberType) => memberType.name === itemTypeName)\n}\n\n/** @internal */\nexport const DEFAULT_MAX_RECURSION_DEPTH = 10\n\n/**\n * Backstop for an initial-value resolver whose request never settles — e.g.\n * a `client.fetch` parked by the studio's network/CORS error handling.\n * Without it the editor hangs in a loading state and the create-document menu\n * loads forever instead of surfacing the failure. Both call sites\n * (`getInitialValueStream`, `getTemplatePermissions`) time out on this bound.\n *\n * @internal\n */\nexport const RESOLVE_INITIAL_VALUE_TIMEOUT_MS = 10_000\n\ntype ResolveInitialValueForType = <TParams extends Record<string, unknown>>(\n /**\n * This is the name of the document.\n */ type: SchemaType,\n /**\n * Params is a sanity context object passed to every initial value function.\n */\n params: TParams,\n /**\n * Maximum recursion depth (default 9).\n */\n maxDepth: number,\n context: InitialValueResolverContext,\n options?: Options,\n) => Promise<any>\n\nconst memoizeResolveInitialValueForType: (\n fn: ResolveInitialValueForType,\n) => ResolveInitialValueForType = (fn) => {\n const resolveInitialValueForTypeCache = new WeakMap<SchemaType, Map<string, Promise<any>>>()\n\n const stableStringify = (obj: any): string => {\n if (obj !== null && typeof obj === 'object') {\n if (Array.isArray(obj)) {\n return `[${obj.map(stableStringify).join(',')}]`\n }\n const keys = Object.keys(obj).sort()\n return `{${keys\n .map((key) => `${JSON.stringify(key)}:${stableStringify(obj[key])}`)\n .join(',')}}`\n }\n return JSON.stringify(obj)\n }\n\n const hashParameters = (\n params: Record<string, unknown>,\n context: InitialValueResolverContext,\n ): string => {\n return stableStringify({\n params,\n context: {\n schemaName: context.schema.name,\n projectId: context.projectId,\n dataset: context.dataset,\n currentUser: context.currentUser?.id,\n },\n })\n }\n\n return async function resolveInitialValueForType(type, params, maxDepth, context, options) {\n if (!options?.useCache) return fn(type, params, maxDepth, context, options)\n\n let typeCache = resolveInitialValueForTypeCache.get(type)\n\n if (!typeCache) {\n typeCache = new Map<string, Promise<any>>()\n resolveInitialValueForTypeCache.set(type, typeCache)\n }\n\n const hash = hashParameters(params, context)\n\n const cachedResult = typeCache.get(hash)\n if (cachedResult) return cachedResult\n\n const result = await fn(type, params, maxDepth, context, options)\n\n // double check after the await\n if (!typeCache.has(hash)) {\n typeCache.set(hash, result)\n }\n return result\n }\n}\n\n/**\n * Resolve initial value for the given schema type (recursively)\n *\n * @internal\n */\nexport const resolveInitialValueForType = memoizeResolveInitialValueForType(\n (type, params, maxDepth = DEFAULT_MAX_RECURSION_DEPTH, context, options): Promise<any> => {\n if (maxDepth <= 0) {\n return Promise.resolve(undefined)\n }\n\n if (isObjectSchemaType(type)) {\n return postTask(() => resolveInitialObjectValue(type, params, maxDepth, context, options))\n }\n\n if (isArraySchemaType(type)) {\n return postTask(() => resolveInitialArrayValue(type, params, maxDepth, context, options))\n }\n\n return resolveValue(type.initialValue, params, context, options)\n },\n)\n\nasync function resolveInitialArrayValue<Params extends Record<string, unknown>>(\n type: SchemaType,\n params: Params,\n maxDepth: number,\n context: InitialValueResolverContext,\n options?: Options,\n): Promise<any> {\n const initialArray = await resolveValue(type.initialValue, undefined, context, options)\n\n if (!Array.isArray(initialArray)) {\n return undefined\n }\n\n return Promise.all(\n initialArray.map(async (initialItem) => {\n const itemType = getItemType(type as ArraySchemaType, initialItem)!\n return isObjectSchemaType(itemType)\n ? {\n // The initial value defined on the parent array field takes precedence over\n // initial values resolved from the array member type's own fields.\n ...deepAssign(\n (await resolveInitialValueForType(\n itemType,\n params,\n maxDepth - 1,\n context,\n options,\n )) || {},\n initialItem as Record<string, unknown>,\n ),\n _key: randomKey(),\n }\n : initialItem\n }),\n )\n}\n\n/** @internal */\nexport async function resolveInitialObjectValue<Params extends Record<string, unknown>>(\n type: ObjectSchemaType,\n params: Params,\n maxDepth: number,\n context: InitialValueResolverContext,\n options?: Options,\n): Promise<any> {\n const initialObject: Record<string, unknown> = {\n ...((await resolveValue(type.initialValue, params, context, options)) || {}),\n }\n\n const fieldValues: Record<string, any> = {}\n await Promise.all(\n type.fields.map(async (field) => {\n const initialFieldValue = await resolveInitialValueForType(\n field.type,\n params,\n maxDepth - 1,\n context,\n options,\n )\n if (initialFieldValue !== undefined && initialFieldValue !== null) {\n fieldValues[field.name] = initialFieldValue\n }\n }),\n )\n\n const merged = deepAssign(fieldValues, initialObject)\n\n if (isDeepEmpty(merged)) {\n return undefined\n }\n\n if (type.name !== 'object') {\n merged._type = type.name\n }\n\n return merged\n}\n","import {type Schema} from '@sanity/types'\n\nimport {useSource} from '../studio/source'\n\n/**\n * React hook that returns the schema registry for the current project\n *\n * @public\n * @returns The schema registry for the current project\n * @example Using the `useSchema` hook\n * ```ts\n * function MyComponent() {\n * const schema = useSchema()\n * // ... do something with the schema ...\n * }\n * ```\n */\nexport function useSchema(): Schema {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n return useSource().schema\n}\n","import {type ConnectionFailedError, type HttpError, isHttpError} from '@sanity/client'\n\n/** @internal */\nexport function isUnauthorizedError(err: unknown): err is HttpError {\n return isHttpError(err) && err.statusCode === 401\n}\n\n/**\n * Whether `err` is a listener/live-events connection the client rejected with a\n * 401. Unlike a data request, the `listen` endpoint never answers 403: access\n * is applied by filtering events, so a rejected connection can only be an\n * invalid or expired session. The rejection is a `ConnectionFailedError`\n * carrying only `status` (no response body, so no `errorCode`), matched by name\n * to survive duplicate `@sanity/client` copies.\n *\n * @internal\n */\nexport function isConnectionSessionError(err: unknown): err is ConnectionFailedError {\n return (\n err instanceof Error &&\n err.name === 'ConnectionFailedError' &&\n 'status' in err &&\n err.status === 401\n )\n}\n\n/**\n * Error codes the API uses on 401s that positively signal an invalid session:\n * - `SIO-401-AEX`: the session has expired\n * - `SIO-401-ANF`: the token resolves to no session at all (\"Session not\n * found\" — revoked on another device, purged after expiry, or a stale/\n * corrupted stored token)\n *\n * Both mean no valid session exists, so both warrant a forced logout.\n */\nconst INVALID_SESSION_ERROR_CODES = ['SIO-401-AEX', 'SIO-401-ANF']\n\n/**\n * Whether a 401 positively signals an invalid session (see\n * {@link INVALID_SESSION_ERROR_CODES}). A 401 *without* one of these codes is\n * a resource-level denial (e.g. an authenticated user lacking a grant —\n * some endpoints answer those with 401, not 403) and must stay\n * caller-domain rather than force a logout; grant denials only happen with\n * a valid session, so they never carry these codes.\n *\n * @internal\n */\nexport function isInvalidSessionError(err: unknown): err is HttpError {\n if (!isUnauthorizedError(err)) return false\n const code = getApiErrorCode(err)\n return code !== undefined && INVALID_SESSION_ERROR_CODES.includes(code)\n}\n\n/**\n * The API's machine-readable `errorCode` from a client error response body\n * (e.g. `SIO-401-AEX` for an expired session), or `undefined` if absent. The\n * `ClientError` exposes the parsed body on `response.body` (typed `unknown`);\n * fall back to the stringified `responseBody` since older error shapes only\n * carry that.\n *\n * @internal\n */\nexport function getApiErrorCode(err: unknown): string | undefined {\n if (!isHttpError(err)) return undefined\n const fromResponse = readErrorCode(err.response.body)\n if (fromResponse) return fromResponse\n const responseBody = 'responseBody' in err ? err.responseBody : undefined\n if (typeof responseBody !== 'string') return undefined\n try {\n return readErrorCode(JSON.parse(responseBody))\n } catch {\n return undefined\n }\n}\n\nfunction readErrorCode(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null || !('errorCode' in value)) return undefined\n const code = value.errorCode\n return typeof code === 'string' ? code : undefined\n}\n","import {type HttpError, isHttpError, isTimeoutError} from '@sanity/client'\nimport isNativeNetworkError from 'is-network-error'\n\n// These live in `util` so that non-studio code (e.g. the document store) can\n// depend on them without importing from `studio`; re-exported here to keep\n// the public API surface and existing import sites unchanged.\nexport {getApiErrorCode, isInvalidSessionError, isUnauthorizedError} from '../../util/apiErrors'\nexport {isTimeoutError}\n\n/**\n * Node / get-it v8 timeout codes. get-it v9 reports timeouts as\n * `TimeoutError` (caught by {@link isTimeoutError}); older transports used\n * `ESOCKETTIMEDOUT` (idle socket) or `ETIMEDOUT` (connect/request deadline)\n * on a plain Error, which `isTimeoutError` no longer matches.\n */\nconst LEGACY_TIMEOUT_CODES = new Set(['ESOCKETTIMEDOUT', 'ETIMEDOUT'])\n\n/**\n * Timeouts the studio should treat as infrastructure failures and must not\n * diagnose via `/check/cors` (the probe would just time out too). Covers\n * get-it v9 / platform `TimeoutError` and leftover get-it v8 / Node codes.\n *\n * @internal\n */\nexport function isRequestTimeoutError(error: unknown): error is Error {\n if (isTimeoutError(error)) return true\n if (typeof error !== 'object' || error === null) return false\n return 'code' in error && typeof error.code === 'string' && LEGACY_TIMEOUT_CODES.has(error.code)\n}\n\n/** @internal */\nexport function isNetworkError(error: unknown): error is Error {\n if (typeof error !== 'object' || error === null) return false\n // get-it sets isNetworkError=true on connection errors.\n if ('isNetworkError' in error && error.isNetworkError === true) return true\n // Treat both get-it header timeouts and platform request-deadline\n // TimeoutErrors as network errors so they get the same treatment.\n if (isRequestTimeoutError(error)) return true\n return isNativeNetworkError(error)\n}\n\n/**\n * Read the Retry-After header off a ClientError, if present. Per RFC 7231,\n * it's either a non-negative delta-seconds integer or an HTTP date.\n *\n * @internal\n */\nexport function parseRetryAfter(err: HttpError): number | undefined {\n const value = err.response.headers['retry-after']\n if (!value) return undefined\n // Numeric-looking values go through the integer path even when out of\n // range, so negative numbers don't accidentally fall through to the date\n // parser (which can interpret them as historic dates).\n if (/^-?\\d+(\\.\\d+)?$/.test(value.trim())) {\n const seconds = Number(value)\n if (Number.isFinite(seconds) && seconds >= 0) return Math.ceil(seconds)\n return undefined\n }\n const dateMs = Date.parse(value)\n if (Number.isFinite(dateMs)) {\n const delta = Math.ceil((dateMs - Date.now()) / 1000)\n return delta > 0 ? delta : 0\n }\n return undefined\n}\n\n/**\n * Infrastructure-level error variants the studio's request-error UI knows\n * how to render. Everything else (4xx other than 429, parse errors, etc.)\n * is caller-domain and is never claimed by the studio.\n *\n * @internal\n */\nexport type RequestErrorClassification =\n | {type: 'networkError'; error: Error}\n | {type: 'serverError'; error: HttpError}\n | {type: 'rateLimited'; error: HttpError; retryAfterSeconds?: number}\n\n/**\n * Classify an error as an infrastructure-level request failure, or return\n * `null` when the error is caller-domain (validation errors, permission\n * denials, conflicts, 404s, ...) and should stay with the caller.\n *\n * Note: 401 is intentionally NOT classified here — whether a 401 means\n * \"invalid session\" (studio concern) or \"this resource refuses you\"\n * (caller concern) is decided by the API's explicit error code, which the\n * channel checks separately (see {@link isInvalidSessionError}).\n *\n * @internal\n */\nexport function classifyRequestError(err: unknown): RequestErrorClassification | null {\n if (isHttpError(err)) {\n if (err.statusCode === 429) {\n return {type: 'rateLimited', error: err, retryAfterSeconds: parseRetryAfter(err)}\n }\n if (err.statusCode >= 500) return {type: 'serverError', error: err}\n // 4xx other than 429 are caller-domain. They carry structured context\n // the caller is better positioned to render than a generic dialog.\n return null\n }\n if (isNetworkError(err)) return {type: 'networkError', error: err}\n return null\n}\n\n/**\n * A workspace-level configuration error: the project or dataset the\n * studio is pointed at doesn't exist. Unlike the infrastructure errors\n * above, these are not transient and not recoverable by retry — the user\n * has to fix `projectId`/`dataset` in their config (or create the missing\n * resource). The studio surfaces these as a full-screen takeover rather\n * than the retry/reload dialog.\n *\n * Which variant we can report depends on what the failing endpoint tells\n * us. Only the project/dataset management API carries a structured\n * discriminator; the generic `/data` 404 can't tell missing-project from\n * missing-dataset apart, so it isn't classified as a config error at all\n * (see {@link classifyConfigError}).\n *\n * @internal\n */\nexport type ConfigErrorClassification = {type: 'projectNotFound'} | {type: 'datasetNotFound'}\n\n/** Shape of the structured fields we read off a 404 response body. */\ninterface NotFoundBody {\n error?: unknown\n attributes?: {type?: unknown}\n}\n\nfunction notFoundBody(err: HttpError): NotFoundBody | undefined {\n const body = err.response.body\n if (!body || typeof body !== 'object') return undefined\n\n const attributes = 'attributes' in body ? body.attributes : undefined\n return {\n error: 'error' in body ? body.error : undefined,\n attributes:\n attributes && typeof attributes === 'object'\n ? {type: 'type' in attributes ? attributes.type : undefined}\n : undefined,\n }\n}\n\n/**\n * Classify a 404 as a studio-configuration error — the project or dataset\n * the studio points at doesn't exist — using only structured response\n * fields (never message text, which isn't stable across endpoints).\n *\n * Recognized structured signals:\n * - `attributes.type === 'project'` → `projectNotFound`\n * (project management API)\n * - `error === 'Dataset not found'` → `datasetNotFound`\n * (dataset management API; a discrete error code, not free-form text)\n *\n * A 404 without one of these structured signals returns `null` and stays\n * caller-domain — including the generic `/data` 404s, which carry no\n * discriminator and so can't be safely attributed to a missing project or\n * dataset. This classifier only reports what the *response* proves.\n *\n * @internal\n */\nexport function classifyConfigError(err: unknown): ConfigErrorClassification | null {\n if (!isHttpError(err) || err.statusCode !== 404) return null\n const body = notFoundBody(err)\n if (!body) return null\n\n // Project management API tags the response with `attributes.type`.\n if (body.attributes?.type === 'project') {\n return {type: 'projectNotFound'}\n }\n\n // Dataset management API returns a discrete `error` code. This is an\n // equality check on a structured field, not a match against free-form\n // `message` text.\n if (body.error === 'Dataset not found') {\n return {type: 'datasetNotFound'}\n }\n\n return null\n}\n\n/**\n * Whether an error originates from a Sanity client request — i.e. one a\n * plugin/customization could have delegated to the studio's error UI via\n * `useStudioErrorHandler()` rather than letting it reach an error\n * boundary. Used to surface a dev-only \"did you mean to opt in?\" tip.\n *\n * @internal\n */\nexport function isClientRequestError(err: unknown): boolean {\n return isHttpError(err) || isNetworkError(err)\n}\n","import {type HttpError} from '@sanity/client'\nimport {BehaviorSubject, isObservable, lastValueFrom, type Observable} from 'rxjs'\n\nimport {classifyRequestError, isInvalidSessionError} from './classify'\nimport {\n type RequestErrorChannel,\n type RequestErrorClaim,\n type RequestErrorReportOptions,\n type StudioErrorHandler,\n} from './types'\n\n/**\n * Best-effort projectId extraction from an HTTP error's request URL\n * (`https://{projectId}.api.sanity.io/...`). Used to route a delegated\n * 401 to the right workspace's auth store for forced logout.\n */\nfunction projectIdFromError(err: HttpError): string | undefined {\n const url = err.response.url\n if (!url) return undefined\n try {\n const host = new URL(url).hostname\n const match = host.match(/^([a-z0-9]+)\\.api\\.sanity\\.(?:io|work)$/)\n return match?.[1]\n } catch {\n return undefined\n }\n}\n\ninterface ParkedEntry {\n /** Re-runs the failed work. Absent for the `handle()` form. */\n retry?: () => void\n}\n\n/**\n * Create the studio's request-error channel. Framework-free — the React\n * side (context provider, dialog rendering) lives in `WorkspacesProvider`.\n *\n * See {@link StudioErrorHandler} for the call-site API and semantics.\n *\n * @internal\n */\nexport function createRequestErrorChannel(): RequestErrorChannel {\n const claimSubject = new BehaviorSubject<RequestErrorClaim | undefined>(undefined)\n let parked: ParkedEntry[] = []\n\n /**\n * Attempt to claim `err` for the studio UI. Returns `true` when claimed\n * (entry parked, dialog state set) and `false` when the error is\n * caller-domain and should be re-thrown by the caller of this function.\n */\n function tryClaim(err: unknown, options: RequestErrorReportOptions, entry: ParkedEntry): boolean {\n if (isInvalidSessionError(err)) {\n // The API positively signals an invalid session (expired or not found,\n // see INVALID_SESSION_ERROR_CODES) — force logout. A 401 *without* such\n // a code is a resource-level denial (some endpoints answer 401, not\n // 403, for authenticated users lacking a grant) and stays\n // caller-domain, same as a 403.\n parked.push(entry)\n // First invalid-session 401 owns the dialog + logout; concurrent\n // ones for the same teardown (including the logout request's own\n // 401) just park behind it rather than re-claiming.\n if (claimSubject.getValue()?.type !== 'unauthorized') {\n claimSubject.next({type: 'unauthorized', error: err, projectId: projectIdFromError(err)})\n }\n return true\n }\n\n const classification = classifyRequestError(err)\n if (!classification) return false\n\n parked.push(entry)\n // First claim owns the dialog; later concurrent failures just park —\n // their retries piggyback on the visible dialog's \"Try again\".\n if (!claimSubject.getValue()) {\n claimSubject.next({\n ...classification,\n retryable: Boolean(options.retryable && entry.retry),\n })\n }\n return true\n }\n\n function retry(): void {\n const entries = parked\n parked = []\n claimSubject.next(undefined)\n for (const entry of entries) {\n // Entries without a retry mechanism (the `handle()` form) stay\n // parked-forever by design: their promise chains were\n // fire-and-surface. Re-running is only possible where the caller\n // gave us something to run.\n entry.retry?.()\n }\n }\n\n async function handle(err: unknown): Promise<never> {\n // A rejection handler can't re-run the request (it already happened),\n // so handled errors are never retryable.\n if (!tryClaim(err, {retryable: false}, {})) throw err\n // Claimed: the dialog is up. Park the chain — there is nothing to\n // re-run, so it stays pending until the user reloads.\n return new Promise<never>(() => {})\n }\n\n function attempt<T>(\n thunk: (attemptNumber: number) => PromiseLike<T> | Observable<T>,\n options: RequestErrorReportOptions = {},\n ): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let attemptNumber = 0\n const tryOnce = () => {\n attemptNumber += 1\n Promise.resolve(attemptNumber)\n .then((n) => {\n const result = thunk(n)\n // Single-shot request observables emit once then complete —\n // their last value is their value.\n return isObservable(result) ? lastValueFrom(result) : result\n })\n .then(resolve, (err) => {\n if (!tryClaim(err, options, {retry: tryOnce})) reject(err)\n })\n }\n tryOnce()\n })\n }\n\n return {\n attempt,\n handle,\n retry,\n claim$: claimSubject.asObservable(),\n }\n}\n\n/**\n * The {@link StudioErrorHandler} used when there is no studio error UI to\n * delegate to — outside a `WorkspacesProvider`, or in a standalone render\n * of a component that normally lives in a Studio.\n *\n * It has no dialog and no retry, so it just runs the work and lets the\n * caller's own error handling take over:\n * - `attempt()` runs the thunk once and resolves/rejects with its result\n * (an observable is drained to its last value, same as the real\n * channel).\n * - `handle()` re-throws, so the next `.catch` in the chain still sees the\n * error.\n *\n * This lets call sites use `useStudioErrorHandler()` unconditionally\n * instead of branching on whether a Studio is present.\n *\n * @internal\n */\nexport const passthroughErrorHandler: StudioErrorHandler = {\n attempt(thunk) {\n return Promise.resolve(1).then((n) => {\n const result = thunk(n)\n return isObservable(result) ? lastValueFrom(result) : result\n })\n },\n handle(err) {\n return Promise.reject(err)\n },\n}\n","import {useContext} from 'react'\nimport {StudioErrorHandlerContext} from 'sanity/_singletons'\n\nimport {passthroughErrorHandler} from './createRequestErrorChannel'\nimport {type StudioErrorHandler} from './types'\n\n/**\n * Access the studio's request-error reporter — the call-site API for\n * delegating unrecoverable request errors (network failures, 5xx, 429)\n * to the studio's built-in error UI.\n *\n * The studio never intercepts requests on its own: plugins and\n * customizations handle their own errors by default (inline errors,\n * toasts, fallbacks). Use this reporter for the failures your code\n * cannot recover from locally.\n *\n * Always returns a handler, so call sites never have to branch on whether\n * a Studio is present. Outside a `WorkspacesProvider` (e.g. a standalone\n * render of a component that normally lives in a Studio) it returns a\n * passthrough handler with no dialog and no retry: `attempt()` just runs\n * the work, and `handle()` re-throws to the caller's own `.catch`.\n *\n * @example\n * ```tsx\n * function MyPluginComponent() {\n * const client = useClient({apiVersion: '2025-02-19'})\n * const {attempt, handle} = useStudioErrorHandler()\n *\n * const loadSettings = useCallback(async () => {\n * // Retryable read: \"Try again\" in the studio dialog re-runs the thunk.\n * const settings = await attempt(\n * () => client.fetch('*[_id == \"myPlugin.settings\"][0]'),\n * {retryable: true},\n * )\n * return settings\n * }, [client, attempt])\n *\n * const save = useCallback(\n * (doc: SanityDocument) =>\n * client\n * .createOrReplace(doc)\n * // Fire-and-surface: a network/5xx failure shows the studio\n * // dialog (reload-only, conservative copy). Caller-domain errors\n * // (validation, permissions) are re-thrown to the next .catch.\n * .catch(handle)\n * .catch(showInlineValidationError),\n * [client, handle],\n * )\n * // ...\n * }\n * ```\n *\n * @beta\n */\nexport function useStudioErrorHandler(): StudioErrorHandler {\n return useContext(StudioErrorHandlerContext) ?? passthroughErrorHandler\n}\n","import {useSource} from '../studio/source'\nimport {type Template} from '../templates/types'\n\n/**\n *\n * @hidden\n * @beta\n */\nexport function useTemplates(): Template[] {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n return useSource().templates\n}\n","/**\n * Maximum size in bytes for document IDs in a single query.\n * This matches the limit used in availability.ts and accounts for\n * the Sanity client's max query size with room for headers.\n */\nexport const MAX_DOCUMENT_ID_CHUNK_SIZE = 11164\n","import QuickLRU from 'quick-lru'\nimport {concat, defer, EMPTY, map, type Observable, of, type OperatorFunction} from 'rxjs'\nimport {tap} from 'rxjs/operators'\n\n/**\n * The interface that any caching layer must implement\n * @internal\n */\ninterface SWRCache<T> {\n /**\n * Note: This will throw if key does not exist. Always check for existence with `has` before calling\n */\n get(key: string): T\n has(key: string): boolean\n set(key: string, value: T): void\n delete(key: string): void\n}\n\nconst createSWRCache = createLRUCache\n\n/**\n *\n * Create an SWR (Stale While Revalidate) rxjs operator that will store the latest value in a cache and emit the last know value upon observable subscription\n * @param options - Options\n * @internal\n */\nexport function createSWR<T>(options: {maxSize: number}) {\n const cache = createSWRCache<T>(options)\n return function rxSwr(key: string): OperatorFunction<T, {fromCache: boolean; value: T}> {\n return (input$: Observable<T>) => {\n return concat(\n defer(() => (cache.has(key) ? of({fromCache: true, value: cache.get(key)}) : EMPTY)),\n input$.pipe(\n tap((result) => cache.set(key, result)),\n map((value) => ({\n fromCache: false,\n value: value,\n })),\n ),\n )\n }\n }\n}\n\n/**\n * For now, the only cache layer implemented is an in-memory LRU.\n * @param options - LRU options\n * @internal\n */\nfunction createLRUCache<T>(options: {maxSize: number}): SWRCache<T> {\n const lru = new QuickLRU<string, {value: T}>(options)\n return {\n get(key: string) {\n const entry = lru.get(key)\n if (!entry) {\n throw new Error(`Key not found in LRU cache: ${key}`)\n }\n return entry.value\n },\n set(key: string, value: T) {\n lru.set(key, {value})\n },\n delete(key: string) {\n lru.delete(key)\n },\n has(key: string) {\n return lru.has(key)\n },\n }\n}\n","/**\n * Shallow equality for plain objects and arrays, comparing entries with `===` one level deep.\n *\n * The object branch iterates with `for..in` instead of `Object.keys` on purpose: it avoids two\n * array allocations per call and benchmarks ~2x faster on the flat records this compares\n * (permission results, pane params, document top levels).\n *\n * @internal\n */\nexport function shallowEquals<T>(a: T, b: T): boolean {\n if (a === b) return true\n if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) return false\n const aIsArray = Array.isArray(a)\n if (aIsArray !== Array.isArray(b)) return false\n if (aIsArray) {\n const arrayA = a as unknown[]\n const arrayB = b as unknown[]\n if (arrayA.length !== arrayB.length) return false\n for (let index = 0; index < arrayA.length; index++) {\n if (arrayA[index] !== arrayB[index]) return false\n }\n return true\n }\n const recordA = a as Record<string, unknown>\n const recordB = b as Record<string, unknown>\n let countA = 0\n let countB = 0\n for (const key in recordA) {\n if (Object.prototype.hasOwnProperty.call(recordA, key)) {\n if (recordA[key] !== recordB[key]) return false\n countA++\n }\n }\n for (const key in recordB) {\n if (Object.prototype.hasOwnProperty.call(recordB, key)) countB++\n }\n return countA === countB\n}\n","import {WarningOutlineIcon} from '@sanity/icons/WarningOutline'\nimport {type PreviewValue} from '@sanity/types'\n\nexport const INCLUDE_FIELDS_QUERY = ['_id', '_rev', '_type']\nexport const INCLUDE_FIELDS = [...INCLUDE_FIELDS_QUERY, '_key']\n\n/**\n * How long to wait after the last subscriber has unsubscribed before resetting the observable and disconnecting the listener.\n * We want to keep the listener alive for a short while after the last subscriber has unsubscribed to avoid unnecessary reconnects.\n * Reduced from 10s to 5s to limit concurrent SSE connections during navigation-heavy sessions.\n */\nexport const LISTENER_RESET_DELAY = 5_000\n\nexport const AVAILABILITY_READABLE = {\n available: true,\n reason: 'READABLE',\n} as const\n\nexport const AVAILABILITY_PERMISSION_DENIED = {\n available: false,\n reason: 'PERMISSION_DENIED',\n} as const\n\nexport const AVAILABILITY_NOT_FOUND = {\n available: false,\n reason: 'NOT_FOUND',\n} as const\n\nexport const AVAILABILITY_VERSION_DELETED = {\n available: false,\n reason: 'VERSION_DELETED',\n} as const\n\nexport const INVALID_PREVIEW_FALLBACK: PreviewValue = {\n title: 'Invalid preview config',\n subtitle: 'Check the error log in the console',\n media: <WarningOutlineIcon />,\n}\n\n// oxlint-disable-next-line typescript/prefer-as-const\nexport const DOCUMENT_SYSTEM_FIELD: '_system' = '_system'\n","import {Observable, type Subscriber} from 'rxjs'\n\nimport {isNonNullable} from '../../util/isNonNullable'\n\ninterface QueueItem {\n args: any[]\n observer: Subscriber<any>\n completed: boolean\n}\n\n// Takes an observable returning function and returns a debounced function that, when called\n// collects its passed arguments until wait time has passed without receiving new calls.\n// When wait period is over, calls the original function with the collected arguments\nexport function debounceCollect<Fn extends (...args: any[]) => Observable<any[]>>(\n fn: Fn,\n wait: number,\n): Fn extends (collectedArgs: [...infer TArgs][]) => Observable<(infer TReturnValue)[]>\n ? (...args: TArgs) => Observable<TReturnValue>\n : never\nexport function debounceCollect(fn: any, wait: number) {\n let timer: ReturnType<typeof setTimeout>\n let queue: Record<number | string, QueueItem | undefined> = {}\n let idx = 0\n return function debounced(...args: any[]) {\n return new Observable((obs) => {\n clearTimeout(timer)\n timer = setTimeout(flush, wait)\n const queueItem: QueueItem = {\n args: args,\n observer: obs,\n completed: false,\n }\n const id = idx++\n queue[id] = queueItem\n return () => {\n // console.log('completed', queueItem.args)\n queueItem.completed = true\n }\n })\n }\n\n function flush() {\n const currentlyFlushingQueue = queue\n queue = {}\n\n const queueItemIds = Object.keys(currentlyFlushingQueue) // Todo: use debug\n // .map(id => {\n // if (currentlyFlushingQueue[id].completed) {\n // console.log('Dropped', currentlyFlushingQueue[id].args)\n // }\n // return id\n // })\n .filter((id) => {\n const queueItem = currentlyFlushingQueue[id]\n\n return queueItem && !queueItem.completed\n })\n\n if (queueItemIds.length === 0) {\n // nothing to do\n return\n }\n const collectedArgs = queueItemIds\n .map((id) => {\n const queueItem = currentlyFlushingQueue[id]\n\n return queueItem && queueItem.args\n })\n .filter(isNonNullable)\n fn(collectedArgs).subscribe({\n next(results: any[]) {\n results.forEach((result, i) => {\n const queueItem = currentlyFlushingQueue[queueItemIds[i]]\n if (queueItem && !queueItem.completed) {\n queueItem.observer.next(results[i])\n }\n })\n },\n complete() {\n queueItemIds.forEach((id) => {\n const entry = currentlyFlushingQueue[id]\n if (entry && !entry.completed) {\n entry.observer.complete()\n }\n })\n },\n error(err: Error) {\n queueItemIds.forEach((id) => {\n const entry = currentlyFlushingQueue[id]\n if (entry && !entry.completed) {\n entry.observer.error(err)\n }\n })\n },\n })\n }\n}\n","import {type SanityClient, type StackablePerspective} from '@sanity/client'\nimport flatten from 'lodash-es/flatten.js'\nimport keyBy from 'lodash-es/keyBy.js'\nimport {combineLatest, defer, from, type Observable, of} from 'rxjs'\nimport {distinctUntilChanged, map, mergeMap, reduce, switchMap} from 'rxjs/operators'\n\nimport {MAX_DOCUMENT_ID_CHUNK_SIZE} from '../util/const'\nimport {getDraftId, getPublishedId, getVersionId} from '../util/draftUtils'\nimport {isRecord} from '../util/isRecord'\nimport {createSWR} from '../util/rxSwr'\nimport {shallowEquals} from '../util/shallowEquals'\nimport {\n AVAILABILITY_NOT_FOUND,\n AVAILABILITY_PERMISSION_DENIED,\n AVAILABILITY_READABLE,\n AVAILABILITY_VERSION_DELETED,\n} from './constants'\nimport {\n type AvailabilityResponse,\n type DocumentAvailability,\n type DocumentStackAvailability,\n type DraftsModelDocumentAvailability,\n type ObservePathsFn,\n} from './types'\nimport {debounceCollect} from './utils/debounceCollect'\n/**\n * Create an SWR operator for document availability\n */\nconst swr = createSWR<DocumentAvailability>({maxSize: 1000})\n\n/**\n * Takes an array of document IDs and puts them into individual chunks.\n * Because document IDs can vary greatly in size, we want to chunk by the length of the\n * combined comma-separated ID set. We try to stay within 11164 bytes - this is about the\n * same length the Sanity client uses for max query size, and accounts for rather large\n * headers to be present - so this _should_ be safe.\n *\n * @param documentIds - Unique document IDs to chunk\n * @returns Array of document ID chunks\n */\nfunction chunkDocumentIds(documentIds: string[]): string[][] {\n let chunk: string[] = []\n let chunkSize = 0\n\n const chunks: string[][] = []\n\n for (const documentId of documentIds) {\n // Reached the max length? start a new chunk\n if (chunkSize + documentId.length + 1 >= MAX_DOCUMENT_ID_CHUNK_SIZE) {\n chunks.push(chunk)\n chunk = []\n chunkSize = 0\n }\n\n chunkSize += documentId.length + 1 // +1 is to account for a comma between IDs\n chunk.push(documentId)\n }\n\n if (!chunks.includes(chunk)) {\n chunks.push(chunk)\n }\n\n return chunks\n}\n\n/**\n * Mutative concat\n * @param array - the array to concat to\n * @param chunks - the items to concat to the array\n */\nfunction mutConcat<T>(array: T[], chunks: T[]) {\n array.push(...chunks)\n return array\n}\n\nfunction createDocumentAvailabilityObserver(\n versionedClient: SanityClient,\n observePaths: ObservePathsFn,\n): (id: string) => Observable<DocumentAvailability> {\n const fetchDocumentReadability = debounceCollect(function fetchDocumentReadability(\n args: string[][],\n ): Observable<DocumentAvailability[]> {\n const uniqueIds = [...new Set(flatten(args))]\n return from(chunkDocumentIds(uniqueIds)).pipe(\n mergeMap(fetchDocumentReadabilityChunked, 10),\n reduce<DocumentAvailability[], DocumentAvailability[]>(mutConcat, []),\n map((res) => args.map(([id]) => res[uniqueIds.indexOf(id)])),\n )\n }, 1)\n\n function fetchDocumentReadabilityChunked(ids: string[]): Observable<DocumentAvailability[]> {\n return defer(() => {\n const requestOptions = {\n url: versionedClient.getDataUrl('doc', ids.join(',')),\n json: true,\n query: {excludeContent: 'true'},\n tag: 'preview.documents-availability',\n }\n return versionedClient.observable.request<AvailabilityResponse>(requestOptions).pipe(\n map((response) => {\n const omitted = keyBy(response.omitted || [], (entry) => entry.id)\n return ids.map((id) => {\n const omittedEntry = omitted[id]\n if (!omittedEntry) {\n // it's not omitted, so it exists and is readable\n return AVAILABILITY_READABLE\n }\n if (omittedEntry.reason === 'existence') {\n return AVAILABILITY_NOT_FOUND\n }\n if (omittedEntry.reason === 'permission') {\n // it's not omitted, so it exists and is readable\n return AVAILABILITY_PERMISSION_DENIED\n }\n throw new Error(`Unexpected reason for omission: \"${omittedEntry.reason}\"`)\n })\n }),\n )\n })\n }\n\n /**\n * Observable of metadata for the document with the given id\n * If we can't read a document it is either because it's not readable or because it doesn't exist\n *\n * @internal\n */\n return function observeDocumentAvailability(id: string): Observable<DocumentAvailability> {\n // check for existence first, observePaths is lightweight\n return observePaths({_id: id}, [['_rev'], ['_system']]).pipe(\n map((res) => ({\n hasRev: isRecord(res) && Boolean('_rev' in res && res?._rev),\n isDeleted: isRecord(res) && res._system?.delete === true,\n })),\n distinctUntilChanged(),\n switchMap(({hasRev, isDeleted}) => {\n if (isDeleted) {\n return of(AVAILABILITY_VERSION_DELETED)\n }\n\n return hasRev\n ? // short circuit: if we can read the _rev field we know it both exists and is readable\n of(AVAILABILITY_READABLE)\n : // we can't read the _rev field for two possible reasons: 1) the document isn't readable or 2) the document doesn't exist\n fetchDocumentReadability(id)\n }),\n swr(id),\n map((ev) => ev.value),\n )\n }\n}\n\nfunction ensurePublished(stack: StackablePerspective[]) {\n return stack.includes('published') ? stack : stack.concat(['published'])\n}\n\nexport function createDocumentStackAvailabilityObserver(\n versionedClient: SanityClient,\n observePaths: ObservePathsFn,\n): (id: string, perspective: StackablePerspective[]) => Observable<DocumentStackAvailability[]> {\n const observeDocumentAvailability = createDocumentAvailabilityObserver(\n versionedClient,\n observePaths,\n )\n\n return (id: string, stack: StackablePerspective[]) => {\n return combineLatest(\n // explicitly check availability for published id (we're not using perspective in the following fetch here)\n ensurePublished(stack).map((perspective) => {\n const versionId =\n perspective === 'drafts'\n ? getDraftId(id)\n : perspective === 'published'\n ? getPublishedId(id)\n : getVersionId(id, perspective)\n return observeDocumentAvailability(versionId).pipe(\n map((availability) => ({availability, id: versionId})),\n )\n }),\n )\n }\n}\n\nexport function createPreviewAvailabilityObserver(\n versionedClient: SanityClient,\n observePaths: ObservePathsFn,\n): (id: string) => Observable<DraftsModelDocumentAvailability> {\n const observeDocumentAvailability = createDocumentAvailabilityObserver(\n versionedClient,\n observePaths,\n )\n /**\n * Returns an observable of metadata for a given drafts model document\n */\n return function observeDocumentPairAvailability(\n id: string,\n {version}: {version?: string} = {},\n ): Observable<DraftsModelDocumentAvailability> {\n const draftId = getDraftId(id)\n const publishedId = getPublishedId(id)\n const versionId = version ? getVersionId(id, version) : undefined\n return combineLatest([\n observeDocumentAvailability(draftId),\n observeDocumentAvailability(publishedId),\n ...(versionId ? [observeDocumentAvailability(versionId)] : []),\n ]).pipe(\n distinctUntilChanged(shallowEquals),\n map(([draftReadability, publishedReadability, versionReadability]) => {\n return {\n draft: draftReadability,\n published: publishedReadability,\n ...(versionReadability\n ? {\n version: versionReadability,\n }\n : {}),\n }\n }),\n )\n }\n}\n","import {\n finalize,\n merge,\n type MonoTypeOperatorFunction,\n Observable,\n share,\n type ShareConfig,\n tap,\n} from 'rxjs'\n\nexport type ShareReplayLatestConfig<T> = ShareConfig<T> & {predicate: (value: T) => boolean}\n\n/**\n * A variant of share that takes a predicate function to determine which value to replay to new subscribers\n * @param predicate - Predicate function to determine which value to replay\n */\nexport function shareReplayLatest<T>(predicate: (value: T) => boolean): MonoTypeOperatorFunction<T>\n\n/**\n * A variant of share that takes a predicate function to determine which value to replay to new subscribers\n * @param config - ShareConfig with additional predicate function\n */\nexport function shareReplayLatest<T>(\n config: ShareReplayLatestConfig<T>,\n): MonoTypeOperatorFunction<T>\n\n/**\n * A variant of share that takes a predicate function to determine which value to replay to new subscribers\n * @param configOrPredicate - Predicate function to determine which value to replay\n * @param config - Optional ShareConfig\n */\nexport function shareReplayLatest<T>(\n configOrPredicate: ShareReplayLatestConfig<T> | ShareReplayLatestConfig<T>['predicate'],\n config?: ShareConfig<T>,\n) {\n return _shareReplayLatest(\n typeof configOrPredicate === 'function'\n ? {predicate: configOrPredicate, ...config}\n : configOrPredicate,\n )\n}\nfunction _shareReplayLatest<T>(config: ShareReplayLatestConfig<T>): MonoTypeOperatorFunction<T> {\n return (source: Observable<T>) => {\n let latest: T | undefined\n let emitted = false\n\n const {predicate, ...shareConfig} = config\n\n const wrapped = source.pipe(\n tap((value) => {\n if (config.predicate(value)) {\n emitted = true\n latest = value\n }\n }),\n finalize(() => {\n emitted = false\n latest = undefined\n }),\n share(shareConfig),\n )\n const emitLatest = new Observable<T>((subscriber) => {\n if (emitted) {\n subscriber.next(\n // this cast is safe because of the emitted check which asserts that we got T from the source\n latest as T,\n )\n }\n subscriber.complete()\n })\n return merge(wrapped, emitLatest)\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {timer} from 'rxjs'\n\nimport {LISTENER_RESET_DELAY} from './constants'\nimport {shareReplayLatest} from './utils/shareReplayLatest'\n\n/**\n * @internal\n * Creates a listener that will emit 'welcome' for all new subscribers immediately, and thereafter emit at every mutation event\n */\nexport function createGlobalListener(client: SanityClient) {\n return client\n .listen(\n '*',\n {},\n {\n events: ['welcome', 'mutation', 'reconnect'],\n includeResult: false,\n includePreviousRevision: false,\n includeMutations: false,\n includeAllVersions: true,\n visibility: 'query',\n effectFormat: 'mendoza',\n tag: 'preview.global',\n },\n )\n .pipe(\n shareReplayLatest({\n predicate: (event) => event.type === 'welcome' || event.type === 'reconnect',\n resetOnRefCountZero: () => timer(LISTENER_RESET_DELAY),\n }),\n )\n}\n","import {type SanityDocument} from '@sanity/types'\nimport {applyPatch, type RawPatch} from 'mendoza'\n\nfunction omitRev(document: SanityDocument | undefined) {\n if (document === undefined) {\n return undefined\n }\n const {_rev, ...doc} = document\n return doc\n}\n\n/**\n *\n * @param document - The document to apply the patch to\n * @param patch - The mendoza patch to apply\n * @param baseRev - The revision of the document that the patch is calculated from. This is used to ensure that the patch is applied to the correct revision of the document\n */\nexport function applyMendozaPatch<T extends SanityDocument | undefined>(\n document: T,\n patch: RawPatch,\n baseRev: string,\n): T | undefined {\n if (baseRev !== document?._rev) {\n throw new Error(\n 'Invalid document revision. The provided patch is calculated from a different revision than the current document',\n )\n }\n const next = applyPatch(omitRev(document), patch)\n return next === null ? undefined : next\n}\n\nexport function applyMutationEventEffects(\n document: SanityDocument | undefined,\n event: {effects: {apply: RawPatch}; previousRev: string; resultRev: string},\n) {\n if (!event.effects) {\n throw new Error(\n 'Mutation event is missing effects. Is the listener set up with effectFormat=mendoza?',\n )\n }\n const next = applyMendozaPatch(document, event.effects.apply, event.previousRev)\n // next will be undefined in case of deletion\n return next ? {...next, _rev: event.resultRev} : undefined\n}\n","import {type MutationEvent, type SanityClient, type WelcomeEvent} from '@sanity/client'\nimport {type SanityDocument} from '@sanity/types'\nimport memoize from 'lodash-es/memoize.js'\nimport uniq from 'lodash-es/uniq.js'\nimport {type RawPatch} from 'mendoza'\nimport {EMPTY, finalize, type Observable, of} from 'rxjs'\nimport {concatMap, map, scan, shareReplay} from 'rxjs/operators'\n\nimport {applyMutationEventEffects} from './utils/applyMendozaPatch'\nimport {debounceCollect} from './utils/debounceCollect'\n\nexport type ListenerMutationEventLike = Pick<\n MutationEvent,\n 'type' | 'documentId' | 'previousRev' | 'resultRev'\n> & {\n effects?: {\n apply: unknown[]\n }\n}\nexport interface ObserveDocumentAPIConfig {\n dataset?: string\n projectId?: string\n apiVersion?: string\n}\n\nexport function createObserveDocument({\n mutationChannel,\n client,\n}: {\n client: SanityClient\n mutationChannel: Observable<WelcomeEvent | ListenerMutationEventLike>\n}) {\n const getBatchFetcher = memoize(\n function getBatchFetcher(apiConfig: {dataset: string; projectId: string; apiVersion: string}) {\n const _client = client.withConfig(apiConfig)\n\n function batchFetchDocuments(ids: [string][]) {\n return _client.observable\n .fetch(`*[_id in $ids]`, {ids: uniq(ids.flat())}, {tag: 'preview.observe-document'})\n .pipe(map((result) => ids.map(([id]) => result.find((r: {_id: string}) => r._id === id))))\n }\n return debounceCollect(batchFetchDocuments, 100)\n },\n (apiConfig) => apiConfig.dataset + apiConfig.projectId + apiConfig.apiVersion,\n )\n\n const MEMO: Record<string, Observable<SanityDocument | undefined>> = {}\n\n function observeDocument(id: string, apiConfig?: ObserveDocumentAPIConfig) {\n const _apiConfig = {\n dataset: apiConfig?.dataset || client.config().dataset!,\n projectId: apiConfig?.projectId || client.config().projectId!,\n apiVersion: apiConfig?.apiVersion || client.config().apiVersion,\n }\n const fetchDocument = getBatchFetcher(_apiConfig)\n return mutationChannel.pipe(\n concatMap((event) => {\n if (event.type === 'welcome') {\n return fetchDocument(id).pipe(map((document) => ({type: 'sync' as const, document})))\n }\n return event.documentId === id ? of(event) : EMPTY\n }),\n scan((current: SanityDocument | undefined, event) => {\n if (event.type === 'sync') {\n return event.document\n }\n if (event.type === 'mutation') {\n return applyMutationEvent(current, event)\n }\n //@ts-expect-error - this should never happen\n throw new Error(`Unexpected event type: \"${event.type}\"`)\n }, undefined),\n )\n }\n return function memoizedObserveDocument(id: string, apiConfig?: ObserveDocumentAPIConfig) {\n const key = apiConfig ? `${id}-${JSON.stringify(apiConfig)}` : id\n if (!(key in MEMO)) {\n MEMO[key] = observeDocument(id, apiConfig).pipe(\n finalize(() => delete MEMO[key]),\n shareReplay({bufferSize: 1, refCount: true}),\n )\n }\n return MEMO[key]\n }\n}\n\nfunction applyMutationEvent(current: SanityDocument | undefined, event: ListenerMutationEventLike) {\n if (event.previousRev !== current?._rev) {\n console.warn('Document out of sync, skipping mutation')\n return current\n }\n if (!event.effects) {\n throw new Error(\n 'Mutation event is missing effects. Is the listener set up with effectFormat=mendoza?',\n )\n }\n return applyMutationEventEffects(\n current,\n event as {effects: {apply: RawPatch}; previousRev: string; resultRev: string},\n )\n}\n","export function keysOf<T extends object>(value: T) {\n return Object.keys(value) as (keyof T)[]\n}\n","import {\n combineLatest,\n from as observableFrom,\n isObservable,\n Observable,\n of as observableOf,\n} from 'rxjs'\nimport {map, mergeAll, scan, switchMap} from 'rxjs/operators'\n\nimport {keysOf} from './keysOf'\n\nfunction setKey(source: Record<string, unknown>, key: any, value: unknown) {\n return {\n ...source,\n [key]: value,\n }\n}\n\ntype Props<K extends keyof any, T> = {\n [P in K]: T | Observable<T>\n}\n\nexport function props<K extends keyof any, T>(options: {wait?: boolean} = {}) {\n return (source: Observable<Props<K, T>>) => {\n return new Observable<Props<K, T>>((observer) => source.subscribe(observer)).pipe(\n switchMap((object) => {\n const keyObservables = keysOf(object).map((key) => {\n const value = object[key]\n return isObservable(value)\n ? observableFrom(value).pipe(map((val) => [key, val]))\n : observableOf([key, value])\n })\n\n return options.wait\n ? combineLatest(keyObservables).pipe(\n map((pairs) => pairs.reduce((acc, [key, value]) => setKey(acc, key, value), {})),\n )\n : observableFrom(keyObservables).pipe(\n mergeAll(),\n scan((acc, [key, value]) => setKey(acc, key, value), {}),\n )\n }),\n )\n }\n}\n","import {type StackablePerspective} from '@sanity/client'\nimport {isCrossDatasetReference, isReference} from '@sanity/types'\nimport uniq from 'lodash-es/uniq.js'\nimport {type Observable, of as observableOf} from 'rxjs'\nimport {distinctUntilChanged, switchMap} from 'rxjs/operators'\n\nimport {isRecord} from '../util/isRecord'\nimport {type ApiConfig, type FieldName, type Previewable, type PreviewPath} from './types'\nimport {props} from './utils/props'\n\nfunction createEmpty(fields: FieldName[]) {\n return fields.reduce((result: Record<string, undefined>, field) => {\n result[field] = undefined\n return result\n }, {})\n}\n\nfunction resolveMissingHeads(value: Record<string, unknown>, paths: string[][]) {\n return paths.filter((path) => !(path[0] in value))\n}\n\nfunction getDocumentId(value: Previewable) {\n if (isReference(value)) {\n return value._ref\n }\n return '_id' in value ? value._id : undefined\n}\n\ntype ObserveFieldsFn = (\n id: string,\n fields: FieldName[],\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n) => Observable<Record<string, unknown> | null>\n\nfunction observePaths(\n value: Previewable,\n paths: PreviewPath[],\n observeFields: ObserveFieldsFn,\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n): Observable<Record<string, unknown> | null> {\n if (!value || typeof value !== 'object') {\n // Reached a leaf. Return as is\n return observableOf(value as null) // @todo\n }\n\n const id = getDocumentId(value)\n\n const currentValue: Record<string, unknown> = id ? {...value, _id: id} : {...value}\n\n if (currentValue._type === 'reference') {\n delete currentValue._type\n delete currentValue._ref\n delete currentValue._weak\n delete currentValue._dataset\n delete currentValue._projectId\n delete currentValue._strengthenOnPublish\n }\n\n const pathsWithMissingHeads = resolveMissingHeads(currentValue, paths)\n\n if (id && pathsWithMissingHeads.length > 0) {\n // Reached a node that is either a document (with _id), or a reference (with _ref) that\n // needs to be \"materialized\"\n\n const nextHeads: string[] = uniq(pathsWithMissingHeads.map((path: string[]) => path[0]))\n\n const refApiConfig = isCrossDatasetReference(value)\n ? {projectId: value._projectId, dataset: value._dataset}\n : apiConfig\n\n return observeFields(id, nextHeads, refApiConfig, perspective, variant).pipe(\n distinctUntilChanged((prev, curr) => prev?._rev === curr?._rev),\n switchMap((snapshot) => {\n if (snapshot === null) {\n return observableOf(null)\n }\n\n return observePaths(\n {\n ...createEmpty(nextHeads),\n ...(isReference(value) ? {...value, ...refApiConfig} : value),\n ...snapshot,\n } as Previewable,\n paths,\n observeFields,\n refApiConfig,\n perspective,\n variant,\n )\n }),\n )\n }\n\n // We have all the fields needed already present on value\n const leads: Record<string, string[][]> = {}\n paths.forEach((path) => {\n const [head, ...tail] = path\n if (!leads[head]) {\n leads[head] = []\n }\n leads[head].push(tail)\n })\n\n const next = Object.keys(leads).reduce((res: Record<string, unknown>, head) => {\n const tails = leads[head].filter((tail) => tail.length > 0)\n if (tails.length === 0) {\n res[head] =\n isRecord(value) || Array.isArray(value)\n ? (value as Record<string, unknown>)[head]\n : undefined\n } else {\n res[head] = observePaths(\n (value as any)[head],\n tails,\n observeFields,\n apiConfig,\n perspective,\n variant,\n )\n }\n return res\n }, currentValue)\n\n return observableOf(next).pipe(props({wait: true}))\n}\n\n// Normalizes path arguments so it supports both dot-paths and array paths, e.g.\n// - ['propA.propB', 'propA.propC']\n// - [['propA', 'propB'], ['propA', 'propC']]\nfunction normalizePaths(path: (FieldName | PreviewPath)[]): PreviewPath[] {\n return path.map((segment: FieldName | PreviewPath) =>\n typeof segment === 'string' ? segment.split('.') : segment,\n )\n}\n\n/**\n * Creates a function that allows observing nested paths on a document.\n * If the path includes a reference, the reference will be \"followed\", allowing for selecting paths within the referenced document.\n * @param options - Requires a function that can observe fields on a document\n * @internal\n */\nexport function createPathObserver(options: {observeFields: ObserveFieldsFn}) {\n const {observeFields} = options\n\n return (\n value: Previewable,\n paths: (FieldName | PreviewPath)[],\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ): Observable<Record<string, unknown> | null> => {\n return observePaths(\n value,\n normalizePaths(paths),\n observeFields,\n apiConfig,\n perspective,\n variant,\n )\n }\n}\n","import {type PreviewableType, type PreviewPath} from '../types'\n\nconst DEFAULT_PREVIEW_PATHS: PreviewPath[] = [['_createdAt'], ['_updatedAt']]\n\n/** @internal */\nexport function getPreviewPaths(preview: PreviewableType['preview']): PreviewPath[] | undefined {\n const selection = preview?.select\n\n if (!selection) return undefined\n\n // Transform the selection dot-notation paths into array paths.\n // Example: ['object.title', 'name'] => [['object', 'title'], ['name']]\n const paths = Object.values(selection).map((value) => String(value).split('.')) || []\n\n // Return the paths with the default preview paths appended.\n return paths.concat(DEFAULT_PREVIEW_PATHS)\n}\n","import {isPortableTextSpan, isPortableTextTextBlock, type PortableTextBlock} from '@sanity/types'\n\nexport function isPortableTextPreviewValue(value: unknown): value is PortableTextBlock[] {\n return Array.isArray(value) && (value.length === 0 || value.some(isPortableTextTextBlock))\n}\n\nexport function extractTextFromBlocks(blocks: unknown): string {\n const firstBlock = Array.isArray(blocks) && blocks.find(isPortableTextTextBlock)\n if (!firstBlock || !firstBlock.children) {\n return ''\n }\n\n return firstBlock.children\n .filter(isPortableTextSpan)\n .map((span) => span.text)\n .join('')\n}\n","import {\n isTitledListValue,\n type PrepareViewOptions,\n type PreviewValue,\n type SchemaType,\n type TitledListValue,\n} from '@sanity/types'\nimport debounce from 'lodash-es/debounce.js'\nimport flatten from 'lodash-es/flatten.js'\nimport get from 'lodash-es/get.js'\nimport isPlainObject from 'lodash-es/isPlainObject.js'\nimport pick from 'lodash-es/pick.js'\nimport uniqBy from 'lodash-es/uniqBy.js'\n\nimport {isRecord} from '../../util/isRecord'\nimport {INVALID_PREVIEW_FALLBACK} from '../constants'\nimport {type PreviewableType} from '../types'\nimport {keysOf} from './keysOf'\nimport {extractTextFromBlocks, isPortableTextPreviewValue} from './portableText'\n\nconst PRESERVE_KEYS = ['_id', '_type', '_upload', '_createdAt', '_updatedAt']\nconst EMPTY: never[] = []\n\ntype SelectedValue = Record<string, unknown>\n\nexport type PrepareInvocationResult = {\n selectedValue?: SelectedValue\n returnValue: null | PreviewValue\n errors: Error[]\n}\n\nconst errorCollector = (() => {\n let errorsByType: Record<string, {error: Error; type: PreviewableType; value: SelectedValue}[]> =\n {}\n\n return {\n add: (type: PreviewableType, value: SelectedValue, error: Error) => {\n // cross dataset referenced types have a `type` (string) property instead of `name`\n const typeName = 'name' in type ? type.name : type.type\n if (!errorsByType[typeName]) {\n errorsByType[typeName] = []\n }\n errorsByType[typeName].push({error: error, type: type, value})\n },\n getAll() {\n return errorsByType\n },\n clear() {\n errorsByType = {}\n },\n }\n})()\n\nconst reportErrors = debounce(() => {\n // oxlint-disable no-console\n const errorsByType = errorCollector.getAll()\n const uniqueErrors = flatten(\n Object.keys(errorsByType).map((typeName) => {\n const entries = errorsByType[typeName]\n return uniqBy(entries, (entry) => entry.error.message)\n }),\n )\n const errorCount = uniqueErrors.length\n if (errorCount === 0) {\n return\n }\n\n console.groupCollapsed(\n `%cHeads up! Got ${\n errorCount === 1 ? 'error' : `${errorCount} errors`\n } while preparing data for preview. Click for details.`,\n 'color: #ff7e7c',\n )\n\n Object.keys(errorsByType).forEach((typeName) => {\n const entries = errorsByType[typeName]\n const first = entries[0]\n console.group(`Check the preview config for schema type \"${typeName}\": %o`, first.type.preview)\n const uniqued = uniqBy(entries, (entry) => entry.error.message)\n uniqued.forEach((entry) => {\n if ((entry.error as any).type === 'returnValueError') {\n const hasPrepare = typeof entry.type.preview?.prepare === 'function'\n const {value, error} = entry\n console.log(\n `Encountered an invalid ${\n hasPrepare\n ? 'return value when calling prepare(%o)'\n : 'value targeted by preview.select'\n }:`,\n value,\n )\n console.error(error)\n }\n if ((entry.error as any).type === 'prepareError') {\n const {value, error} = entry\n console.log('Encountered an error when calling prepare(%o):', value)\n console.error(error)\n }\n })\n console.groupEnd()\n })\n console.groupEnd()\n errorCollector.clear()\n // oxlint-enable no-console\n}, 1000)\n\nconst isRenderable =\n (fieldName: string) =>\n (value: unknown): Error[] => {\n const type = typeof value\n if (\n value === null ||\n type === 'undefined' ||\n type === 'string' ||\n type === 'number' ||\n type === 'boolean'\n ) {\n return EMPTY\n }\n return [\n assignType(\n 'returnValueError',\n new Error(\n `The \"${fieldName}\" field should be a string, number, boolean, undefined or null, instead saw ${inspect(\n value,\n )}`,\n ),\n ),\n ]\n }\nconst FIELD_NAME_VALIDATORS: Record<string, (value: unknown) => Error[]> = {\n media: () => {\n // not sure how to validate media as it would possibly involve executing a function and check the\n // return value\n return EMPTY\n },\n title: isRenderable('title'),\n subtitle: isRenderable('subtitle'),\n description: isRenderable('description'),\n imageUrl: isRenderable('imageUrl'),\n date: isRenderable('date'),\n}\n\nfunction inspect(val: unknown, prefixType = true): string {\n if (isRecord(val)) {\n const keys = Object.keys(val)\n const ellipse = keys.length > 3 ? '...' : ''\n const prefix = `object with keys `\n return `${prefixType ? prefix : ''}{${keys.slice(0, 3).join(', ')}${ellipse}}`\n }\n if (Array.isArray(val)) {\n const ellipse = val.length > 3 ? '...' : ''\n const prefix = `array with `\n return `${prefixType ? prefix : ''}[${val.map((v) => inspect(v, false))}${ellipse}]`\n }\n return `the ${typeof val} ${val}`\n}\n\nfunction validateFieldValue(fieldName: string, fieldValue: unknown) {\n if (typeof fieldValue === 'undefined') {\n return EMPTY\n }\n const validator = FIELD_NAME_VALIDATORS[fieldName]\n return (validator && validator(fieldValue)) || EMPTY\n}\n\nfunction assignType(type: string, error: Error) {\n return Object.assign(error, {type})\n}\n\nfunction validatePreparedValue(preparedValue: PreviewValue | null) {\n if (!isPlainObject(preparedValue) || preparedValue === null) {\n return [\n assignType(\n 'returnValueError',\n new Error(\n `Invalid return value. Expected a plain object with at least a 'title' field, instead saw ${inspect(\n preparedValue,\n )}`,\n ),\n ),\n ]\n }\n\n return Object.entries(preparedValue).reduce<Error[]>((acc, [fieldName, fieldValue]) => {\n return [...acc, ...validateFieldValue(fieldName, fieldValue)]\n }, EMPTY)\n}\n\nfunction validateReturnedPreview(result: PrepareInvocationResult) {\n return {\n ...result,\n errors: [...(result.errors || []), ...validatePreparedValue(result.returnValue)],\n }\n}\n\nfunction defaultPrepare(value: SelectedValue) {\n return keysOf(value).reduce((acc: SelectedValue, fieldName: keyof SelectedValue) => {\n const val = value[fieldName]\n return {\n ...acc,\n [fieldName]: isPortableTextPreviewValue(val) ? extractTextFromBlocks(val) : val,\n }\n }, {})\n}\n\nexport function invokePrepare(\n type: PreviewableType,\n value: SelectedValue,\n viewOptions: PrepareViewOptions = {},\n): PrepareInvocationResult {\n const prepare = type.preview?.prepare\n try {\n return {\n returnValue: prepare\n ? (prepare(value, viewOptions) as Record<string, unknown>)\n : defaultPrepare(value),\n errors: EMPTY,\n }\n } catch (error) {\n return {\n returnValue: null,\n errors: [assignType('prepareError', error)],\n }\n }\n}\n\nfunction withErrors(\n result: {errors: Error[]},\n type: PreviewableType,\n selectedValue: SelectedValue,\n): PreviewValue {\n result.errors.forEach((error) => errorCollector.add(type, selectedValue, error))\n reportErrors()\n\n return INVALID_PREVIEW_FALLBACK\n}\n\ninterface EnumListOptions {\n list: TitledListValue[] | unknown[]\n}\n\nfunction hasEnumListOptions(\n type: SchemaType,\n): type is SchemaType & {options: SchemaType['options'] & EnumListOptions} {\n const options = type.options && typeof type.options === 'object' ? type.options : false\n if (!options || !('list' in options)) {\n return false\n }\n\n const listOptions = (options as EnumListOptions).list\n return Array.isArray(listOptions)\n}\n\nfunction getListOptions(type: SchemaType): TitledListValue[] | undefined {\n if (!hasEnumListOptions(type)) {\n return undefined\n }\n\n const listOptions = type.options.list as EnumListOptions['list']\n return listOptions.map((option) =>\n isTitledListValue(option) ? option : ({title: option, value: option} as TitledListValue),\n )\n}\n\n/** @internal */\nexport function prepareForPreview(\n rawValue: unknown,\n type: PreviewableType,\n viewOptions: PrepareViewOptions = {},\n): PreviewValue & {_createdAt?: string; _updatedAt?: string} {\n const hasCustomPrepare = typeof type.preview?.prepare === 'function'\n const selection: Record<string, string> = type.preview?.select || {}\n const targetKeys = Object.keys(selection)\n\n const selectedValue = targetKeys.reduce<Record<string, unknown>>((acc, key) => {\n // Find the field the value belongs to\n const typeWithFields = 'fields' in type ? type : null\n const targetFieldName = selection[key]\n const valueField = typeWithFields?.fields?.find((f) => f.name === targetFieldName)\n const listOptions = valueField && getListOptions(valueField.type)\n\n // If the user has _not_ specified a `prepare()` function for the preview, and the\n // field type has an `options.list`, we want to use the title of the selected item\n // as the preview value. If, however, there _is_ a custom `prepare()`, we leave this\n // mapping up to the user to perform should they want to. This is both to maintain\n // backwards compatiblity, but also to allow using the raw value for prepare operations\n if (!hasCustomPrepare && listOptions) {\n // Find the selected option that matches the raw value\n const selectedOption =\n listOptions && listOptions.find((opt) => opt.value === get(rawValue, selection[key]))\n acc[key] = selectedOption ? selectedOption.value : get(rawValue, selection[key])\n } else {\n acc[key] = get(rawValue, selection[key])\n }\n\n return acc\n }, {})\n\n const prepareResult = invokePrepare(type, selectedValue, viewOptions)\n if (prepareResult.errors.length > 0) {\n return withErrors(prepareResult, type, selectedValue)\n }\n\n const returnValueResult = validateReturnedPreview(prepareResult)\n return returnValueResult.errors.length > 0\n ? withErrors(returnValueResult, type, selectedValue)\n : {...pick(rawValue, PRESERVE_KEYS), ...prepareResult.returnValue}\n}\n","import {type StackablePerspective} from '@sanity/client'\nimport {\n isCrossDatasetReference,\n isCrossDatasetReferenceSchemaType,\n isReferenceSchemaType,\n type PrepareViewOptions,\n} from '@sanity/types'\nimport isPlainObject from 'lodash-es/isPlainObject.js'\nimport {type Observable, of} from 'rxjs'\nimport {map, switchMap} from 'rxjs/operators'\n\nimport {type ObserveForPreviewFn} from './documentPreviewStore'\nimport {\n type ApiConfig,\n type ObserveDocumentTypeFromIdFn,\n type ObservePathsFn,\n type PreparedSnapshot,\n type Previewable,\n type PreviewableType,\n} from './types'\nimport {getPreviewPaths} from './utils/getPreviewPaths'\nimport {invokePrepare, prepareForPreview} from './utils/prepareForPreview'\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return isPlainObject(value)\n}\n\nfunction isReference(value: unknown): value is {_ref: string} {\n return isPlainObject(value)\n}\n\n/**\n * Takes a value and its type and prepares a snapshot for it that can be passed to a preview component\n * @internal\n */\nexport function createPreviewObserver(context: {\n observeDocumentTypeFromId: ObserveDocumentTypeFromIdFn\n observePaths: ObservePathsFn\n}): ObserveForPreviewFn {\n const {observeDocumentTypeFromId, observePaths} = context\n\n return function observeForPreview(\n value: Previewable,\n type: PreviewableType,\n options: {\n viewOptions?: PrepareViewOptions\n apiConfig?: ApiConfig\n perspective?: StackablePerspective[]\n variant?: string\n } = {},\n ): Observable<PreparedSnapshot> {\n const {viewOptions = {}, apiConfig, perspective, variant} = options\n if (isCrossDatasetReferenceSchemaType(type)) {\n // if the value is of type crossDatasetReference, but has no _ref property, we cannot prepare any value for the preview\n // and the most appropriate thing to do is to return `undefined` for snapshot\n if (!isCrossDatasetReference(value)) {\n return of({snapshot: undefined})\n }\n\n const refApiConfig = {projectId: value._projectId, dataset: value._dataset}\n\n return observeDocumentTypeFromId(value._ref, refApiConfig, perspective, variant).pipe(\n switchMap((typeName) => {\n if (typeName) {\n const refType = type.to.find((toType) => toType.type === typeName)\n if (refType) {\n return observeForPreview(value, refType, {\n apiConfig: refApiConfig,\n viewOptions,\n perspective,\n variant,\n })\n }\n }\n return of({snapshot: undefined})\n }),\n )\n }\n if (isReferenceSchemaType(type)) {\n // if the value is of type reference, but has no _ref property, we cannot prepare any value for the preview\n // and the most appropriate thing to do is to return `undefined` for snapshot\n if (!isReference(value)) {\n return of({snapshot: undefined})\n }\n // Previewing references actually means getting the referenced value,\n // and preview using the preview config of its type\n // We do this since there's no way of knowing the type of the referenced value by looking at the reference value alone\n return observeDocumentTypeFromId(value._ref, undefined, perspective, variant).pipe(\n switchMap((typeName) => {\n if (typeName) {\n const refType = type.to.find((toType) => toType.name === typeName)\n if (refType) {\n return observeForPreview(value, refType, {perspective, variant})\n }\n }\n // todo: in case we can't read the document type, we can figure out the reason why e.g. whether it's because\n // the document doesn't exist or it's not readable due to lack of permission.\n // We can use the \"observeDocumentAvailability\" function\n // for this, but currently not sure if needed\n return of({snapshot: undefined})\n }),\n )\n }\n const paths = getPreviewPaths(type.preview)\n if (paths) {\n return observePaths(value, paths, apiConfig, perspective, variant).pipe(\n map((snapshot) => ({\n type: type,\n snapshot: snapshot ? prepareForPreview(snapshot, type, viewOptions) : null,\n })),\n )\n }\n\n // Note: this case is typically rare (or non-existent) and occurs only if\n // the SchemaType doesn't have a `select` field. The schema compiler\n // provides a default `preview` implementation for `object`s, `image`s,\n // `file`s, and `document`s\n return of({\n type,\n snapshot:\n value && isRecord(value) ? invokePrepare(type, value, viewOptions).returnValue : null,\n })\n }\n}\n","import {type SanityDocument} from '@sanity/types'\nimport {combineLatest, type Observable, of} from 'rxjs'\nimport {map, switchMap} from 'rxjs/operators'\n\nimport {getIdPair} from '../util/draftUtils'\nimport {isRecord} from '../util/isRecord'\nimport {\n type DraftsModelDocument,\n type ObserveDocumentAvailabilityFn,\n type ObservePathsFn,\n type PreviewPath,\n} from './types'\n\nexport function createObservePathsDocumentPair(options: {\n observeDocumentPairAvailability: ObserveDocumentAvailabilityFn\n observePaths: ObservePathsFn\n}): <T extends SanityDocument = SanityDocument>(\n id: string,\n paths: PreviewPath[],\n) => Observable<DraftsModelDocument<T>> {\n const {observeDocumentPairAvailability, observePaths} = options\n\n const ALWAYS_INCLUDED_SNAPSHOT_PATHS: PreviewPath[] = [['_updatedAt'], ['_createdAt'], ['_type']]\n\n return function observePathsDocumentPair<T extends SanityDocument = SanityDocument>(\n id: string,\n paths: PreviewPath[],\n {version}: {version?: string} = {},\n ): Observable<DraftsModelDocument<T>> {\n const {draftId, publishedId, versionId} = getIdPair(id, {version})\n\n return observeDocumentPairAvailability(draftId, {version}).pipe(\n switchMap((availability) => {\n if (\n !availability.draft.available &&\n !availability.published.available &&\n !availability.version?.available\n ) {\n // short circuit, neither draft nor published is available so no point in trying to get a snapshot\n return of({\n id: publishedId,\n type: null,\n draft: {\n availability: availability.draft,\n snapshot: undefined,\n },\n published: {\n availability: availability.published,\n snapshot: undefined,\n },\n ...(availability.version\n ? {\n version: {\n availability: availability.version,\n snapshot: undefined,\n },\n }\n : {}),\n })\n }\n\n const snapshotPaths = [...paths, ...ALWAYS_INCLUDED_SNAPSHOT_PATHS]\n\n return combineLatest([\n observePaths({_type: 'reference', _ref: draftId}, snapshotPaths),\n observePaths({_type: 'reference', _ref: publishedId}, snapshotPaths),\n ...(version ? [observePaths({_type: 'reference', _ref: versionId}, snapshotPaths)] : []),\n ]).pipe(\n map(([draftSnapshot, publishedSnapshot, versionSnapshot]) => {\n // note: assume type is always the same\n const type =\n (isRecord(versionSnapshot) && '_type' in versionSnapshot && versionSnapshot._type) ||\n (isRecord(draftSnapshot) && '_type' in draftSnapshot && draftSnapshot._type) ||\n (isRecord(publishedSnapshot) &&\n '_type' in publishedSnapshot &&\n publishedSnapshot._type) ||\n null\n\n return {\n id: publishedId,\n type: typeof type === 'string' ? type : null,\n draft: {\n availability: availability.draft,\n snapshot: draftSnapshot as T,\n },\n published: {\n availability: availability.published,\n snapshot: publishedSnapshot as T,\n },\n ...(availability.version\n ? {\n version: {\n availability: availability.version,\n snapshot: versionSnapshot as T,\n },\n }\n : {}),\n }\n }),\n )\n }),\n )\n }\n}\n","import {type QueryParams, type SanityClient} from '@sanity/client'\nimport sortedIndex from 'lodash-es/sortedIndex.js'\nimport {of} from 'rxjs'\nimport {distinctUntilChanged, filter, map, mergeMap, scan, tap} from 'rxjs/operators'\n\nimport {type SourceClientOptions} from '../config/types'\nimport {versionedClient} from '../studioClient'\n\nexport type DocumentIdSetObserverState = {\n status: 'reconnecting' | 'connected'\n documentIds: string[]\n}\n\ninterface LiveDocumentIdSetOptions {\n insert?: 'sorted' | 'prepend' | 'append'\n apiVersion?: SourceClientOptions['apiVersion']\n}\n\nexport function createDocumentIdSetObserver(client: SanityClient) {\n return function observe(\n queryFilter: string,\n params?: QueryParams,\n options: LiveDocumentIdSetOptions = {},\n ) {\n const {insert: insertOption = 'sorted', apiVersion} = options\n\n const query = `*[${queryFilter}]._id`\n function fetchFilter() {\n return versionedClient(client, apiVersion)\n .observable.fetch(query, params, {\n tag: 'preview.observe-document-set.fetch',\n })\n .pipe(\n tap((result) => {\n if (!Array.isArray(result)) {\n throw new Error(\n `Expected query to return array of documents, but got ${typeof result}`,\n )\n }\n }),\n )\n }\n return versionedClient(client, apiVersion)\n .observable.listen(`*[${queryFilter}]`, params, {\n visibility: 'transaction',\n events: ['welcome', 'mutation', 'reconnect'],\n includeResult: false,\n includeMutations: false,\n includeAllVersions: true,\n tag: 'preview.observe-document-set.listen',\n })\n .pipe(\n mergeMap((event) => {\n return event.type === 'welcome'\n ? fetchFilter().pipe(map((result) => ({type: 'fetch' as const, result})))\n : of(event)\n }),\n scan(\n (\n state: DocumentIdSetObserverState | undefined,\n event,\n ): DocumentIdSetObserverState | undefined => {\n if (event.type === 'reconnect') {\n return {\n documentIds: state?.documentIds || [],\n ...state,\n status: 'reconnecting' as const,\n }\n }\n if (event.type === 'fetch') {\n return {...state, status: 'connected' as const, documentIds: event.result}\n }\n if (event.type === 'mutation') {\n if (event.transition === 'update') {\n // ignore updates, as we're only interested in documents appearing and disappearing from the set\n return state\n }\n if (event.transition === 'appear') {\n return {\n status: 'connected',\n documentIds: insert(state?.documentIds || [], event.documentId, insertOption),\n }\n }\n if (event.transition === 'disappear') {\n return {\n status: 'connected',\n documentIds: state?.documentIds\n ? state.documentIds.filter((id) => id !== event.documentId)\n : [],\n }\n }\n }\n return state\n },\n undefined,\n ),\n distinctUntilChanged(),\n filter(\n (state: DocumentIdSetObserverState | undefined): state is DocumentIdSetObserverState =>\n state !== undefined,\n ),\n )\n }\n}\n\nfunction insert<T>(array: T[], element: T, strategy: 'sorted' | 'prepend' | 'append') {\n let index\n if (strategy === 'prepend') {\n index = 0\n } else if (strategy === 'append') {\n index = array.length\n } else {\n index = sortedIndex(array, element)\n }\n\n return array.toSpliced(index, 0, element)\n}\n","import {type ClientPerspective} from '@sanity/client'\n\nimport {type SourceClientOptions} from '../../config/types'\n\n/**\n * @internal This is the client options used for the releases studio client, using the `X` API version for now\n * Will change to a specific version soon.\n * TODO: Remove after API version is stable and support releases\n */\nexport const RELEASES_STUDIO_CLIENT_OPTIONS: SourceClientOptions = {\n apiVersion: 'v2025-02-19',\n}\n\n/**\n * @internal Checks if the perspective is a release perspective\n * TODO: Remove after API version is stable and support releases\n */\nexport const isReleasePerspective = (\n perspective: ClientPerspective | undefined | string | string[],\n): boolean => {\n if (Array.isArray(perspective)) {\n return true\n }\n return false\n}\n","import {VARIANTS_STUDIO_CLIENT_OPTIONS} from '../store/constants'\n\n/**\n * Resolves the API version to use for a query that may carry a `variant` option.\n *\n * Fetching with a variant is only supported on the variants API version, which takes precedence\n * over any other version the caller would otherwise use (e.g. the releases version for stacked\n * perspectives).\n *\n * Intended to be used with `versionedClient`:\n *\n * ```ts\n * versionedClient(client, variantApiVersion(variant, releaseApiVersion))\n * ```\n *\n * @internal\n */\nexport function variantApiVersion(\n variant: string | undefined,\n fallbackApiVersion?: string,\n): string | undefined {\n return variant ? VARIANTS_STUDIO_CLIENT_OPTIONS.apiVersion : fallbackApiVersion\n}\n","export function hasEqualFields(fields: string[]) {\n return (object: Record<string, any> | null, otherObject: Record<string, any> | null) => {\n if (object === otherObject) {\n return true\n }\n if (!object || !otherObject) {\n return false\n }\n if (typeof object !== 'object' || typeof otherObject !== 'object') {\n return false\n }\n return fields.every((field) => object[field] === otherObject[field])\n }\n}\n","const id = <T>(value: T): T => value\n\ntype ItemSelector<T> = (element: T) => any\n\n// Takes an array and checks if each item is unique,\n// optionally by specifying an itemSelector function that will be called with\n// each item, returning the value to compare for uniqueness\nexport function isUniqueBy<T>(array: Array<T>, itemSelector: ItemSelector<T> = id): boolean {\n let prevItem\n let currItem\n for (let i = 0; i < array.length; i++) {\n if (i === 0) {\n prevItem = itemSelector(array[i])\n continue\n }\n currItem = itemSelector(array[i])\n if (prevItem !== currItem) {\n return false\n }\n prevItem = currItem\n }\n return true\n}\n","type SearchPathSegment = string | number | []\n\nconst GROQ_KEYWORDS = ['match', 'in', 'asc', 'desc', 'true', 'false', 'null']\nconst VALID_FIELD = /^[a-zA-Z_][a-zA-Z0-9_]*$/\n\n/** @internal */\nexport const fieldNeedsEscape = (fieldName: string): boolean =>\n !VALID_FIELD.test(fieldName) || GROQ_KEYWORDS.includes(fieldName)\n\n/** @internal */\nexport const escapeField = (fieldName: string): string => `[\"${fieldName}\"]`\n\nconst escapeFirst = (fieldName: string): string => `@${escapeField(fieldName)}`\n\nconst isEmptyArray = (value: unknown): value is [] => Array.isArray(value) && value.length === 0\n\n/** @internal */\nexport const joinPath = (pathArray: SearchPathSegment[]): string => {\n let path = ''\n for (let i = 0; i < pathArray.length; i++) {\n const pathSegment = pathArray[i]\n if (isEmptyArray(pathSegment)) {\n path += `[]`\n continue\n }\n\n if (typeof pathSegment === 'number') {\n path += `[${pathSegment}]`\n continue\n }\n\n const isFirst = i === 0\n const needsEscape = fieldNeedsEscape(pathSegment)\n\n if (needsEscape) {\n path = isFirst ? escapeFirst(pathSegment) : `${path}${escapeField(pathSegment)}`\n } else {\n path = isFirst ? pathSegment : `${path}.${pathSegment}`\n }\n }\n\n return path\n}\n","import identity from 'lodash-es/identity.js'\nimport sortBy from 'lodash-es/sortBy.js'\nimport values from 'lodash-es/values.js'\n\nimport {escapeField, fieldNeedsEscape} from '../../util/searchUtils'\nimport {INCLUDE_FIELDS_QUERY} from '../constants'\nimport {type FieldName, type Id, type Selection} from '../types'\n\n/** @internal */\nexport type CombinedSelection = {\n ids: Id[]\n fields: FieldName[]\n map: number[]\n}\n\ntype Doc = {\n _id: string\n}\n\ntype Result = Doc[]\n\nexport function combineSelections(selections: Selection[]): CombinedSelection[] {\n return values(\n selections.reduce((output: {[key: string]: any}, [id, fields], index) => {\n const key = sortBy(fields.join(','), identity).join('.')\n if (!output[key]) {\n output[key] = {fields: fields, ids: [], map: []}\n }\n const idx = output[key].ids.length\n output[key].ids[idx] = id\n output[key].map[idx] = index\n return output\n }, {}),\n )\n}\n\nfunction stringifyId(id: string) {\n return JSON.stringify(id)\n}\n\nconst maybeEscape = (fieldName: string) =>\n fieldNeedsEscape(fieldName) ? `\"${fieldName}\": @${escapeField(fieldName)}` : fieldName\n\nfunction toSubQuery({ids, fields}: {ids: string[]; fields: string[]}) {\n const allFields = [...INCLUDE_FIELDS_QUERY, ...fields]\n return `*[_id in [${ids.map(stringifyId).join(',')}]][0...${ids.length}]{${allFields\n .map(maybeEscape)\n .join(',')}}`\n}\n\nexport function toQuery(combinedSelections: CombinedSelection[]): string {\n return `[${combinedSelections.map(toSubQuery).join(',')}][0...${combinedSelections.length}]`\n}\n\nexport function reassemble(\n queryResult: Result[],\n combinedSelections: CombinedSelection[],\n): (Doc | null)[] {\n return queryResult.reduce((reprojected: (Doc | null)[], subResult, index) => {\n const map = combinedSelections[index].map\n map.forEach((resultIdx, i) => {\n const id = combinedSelections[index].ids[i]\n const found = subResult.find((doc) => doc._id === id)\n reprojected[resultIdx] = found || null\n })\n return reprojected\n }, [])\n}\n","import {type SanityClient, type StackablePerspective} from '@sanity/client'\nimport difference from 'lodash-es/difference.js'\nimport flatten from 'lodash-es/flatten.js'\nimport memoize from 'lodash-es/memoize.js'\nimport {\n combineLatest,\n concat,\n defer,\n EMPTY,\n from,\n fromEvent,\n merge,\n type Observable,\n of,\n retry,\n timer,\n} from 'rxjs'\nimport {\n distinctUntilChanged,\n filter,\n map,\n mergeMap,\n reduce,\n share,\n shareReplay,\n startWith,\n switchMap,\n tap,\n} from 'rxjs/operators'\n\nimport {RELEASES_STUDIO_CLIENT_OPTIONS} from '../releases/util/releasesClient'\nimport {versionedClient} from '../studioClient'\nimport {MAX_DOCUMENT_ID_CHUNK_SIZE} from '../util/const'\nimport {getPublishedId, idMatchesPerspective, isVersionId} from '../util/draftUtils'\nimport {variantApiVersion} from '../variants/util/variantApiVersion'\nimport {INCLUDE_FIELDS} from './constants'\nimport {\n type ApiConfig,\n type FieldName,\n type Id,\n type InvalidationChannelEvent,\n type Selection,\n} from './types'\nimport {debounceCollect} from './utils/debounceCollect'\nimport {hasEqualFields} from './utils/hasEqualFields'\nimport {isUniqueBy} from './utils/isUniqueBy'\nimport {type CombinedSelection, combineSelections, reassemble, toQuery} from './utils/optimizeQuery'\n\n/**\n * Chunks combined selections into smaller groups based on the total byte size of document IDs.\n * This prevents queries from becoming too large and timing out.\n *\n * Similar to chunkDocumentIds in availability.ts, but handles CombinedSelection structure.\n *\n * @param combinedSelections - The combined selections to chunk\n * @returns Array of chunked combined selections, each within the size limit\n * @internal\n */\nexport function chunkCombinedSelections(\n combinedSelections: CombinedSelection[],\n): CombinedSelection[][] {\n const chunks: CombinedSelection[][] = []\n\n for (const selection of combinedSelections) {\n let chunk: string[] = []\n let chunkMap: number[] = []\n let chunkSize = 0\n\n for (let i = 0; i < selection.ids.length; i++) {\n const id = selection.ids[i]\n // +3 accounts for quotes and comma in GROQ request structure: [\"id1\",\"id2\"]\n const idSize = id.length + 3\n\n // Reached the max length? Start a new chunk\n if (chunkSize + idSize >= MAX_DOCUMENT_ID_CHUNK_SIZE && chunk.length > 0) {\n chunks.push([{ids: chunk, fields: selection.fields, map: chunkMap}])\n chunk = []\n chunkMap = []\n chunkSize = 0\n }\n\n chunk.push(id)\n chunkMap.push(selection.map[i])\n chunkSize += idSize\n }\n\n // Push overflowing IDs to the last chunk\n // If there are any remaining IDs from the previous check\n if (chunk.length > 0) {\n chunks.push([{ids: chunk, fields: selection.fields, map: chunkMap}])\n }\n }\n\n return chunks\n}\n\n/**\n * Cache key for the combination of perspective stack and variant a fetch is scoped to. Preview\n * values differ per combination, so caches must never be shared across them.\n */\nfunction getPerspectiveCacheKey(\n perspective: StackablePerspective[] | undefined,\n variant: string | undefined,\n): string {\n const perspectiveKey = perspective?.join('-') || 'raw'\n return variant ? `${perspectiveKey}-variant:${variant}` : perspectiveKey\n}\n\ntype CachedFieldObserver = {\n id: Id\n fields: FieldName[]\n changes$: Observable<any>\n}\n\ntype Cache = {\n [id: string]: CachedFieldObserver[]\n}\n\n/**\n * Note: this should be the minimal interface createObserveFields needs to function\n * It should be kept compatible with the Sanity Client\n */\nexport interface ClientLike {\n withConfig(config: ApiConfig): ClientLike\n observable: {\n fetch: (\n query: string,\n params: Record<string, string>,\n options: {tag: string},\n ) => Observable<unknown>\n }\n}\n\n/**\n * Creates a function that allows observing individual fields on a document.\n * It will automatically debounce and batch requests, and maintain an in-memory cache of the latest field values\n * @param options - Options to use when creating the observer\n * @internal\n */\nexport function createObserveFields(options: {\n client: SanityClient\n invalidationChannel: Observable<InvalidationChannelEvent>\n}) {\n const {client: currentDatasetClient, invalidationChannel} = options\n\n function fetchAllDocumentPathsWith(\n client: SanityClient,\n perspective?: StackablePerspective[],\n variant?: string,\n ) {\n return function fetchAllDocumentPath(selections: Selection[]) {\n const combinedSelections = combineSelections(selections)\n // If any document is a version document we need to use the release API version\n const useReleaseVersion =\n (perspective && perspective.length > 0) ||\n combinedSelections.some((selection) => selection.ids.some(isVersionId))\n\n const apiClient = versionedClient(\n client,\n variantApiVersion(\n variant,\n useReleaseVersion ? RELEASES_STUDIO_CLIENT_OPTIONS.apiVersion : undefined,\n ),\n )\n\n // Chunk the selections to avoid massive queries that timeout\n const selectionChunks = chunkCombinedSelections(combinedSelections)\n\n // Helper to fetch a single chunk\n const fetchChunk = (chunk: CombinedSelection[]) =>\n apiClient.observable\n .fetch(toQuery(chunk), {}, {tag: 'preview.document-paths', perspective, variant})\n .pipe(\n retry({\n delay: (_: unknown, attempt) => timer(Math.min(30_000, attempt * 1000)),\n }),\n map((result: any) => reassemble(result, chunk)),\n )\n\n // No chunks - return empty array early\n if (selectionChunks.length === 0) {\n return of([])\n }\n\n // Single chunk - no merging needed (most common case)\n // Kept for performance reasons, as it is the common case (no massive releases) and faster\n if (selectionChunks.length === 1) {\n return fetchChunk(selectionChunks[0])\n }\n\n // Multiple chunks - fetch in parallel and merge results\n // Each chunk's reassemble places results at their original map indices\n // We collect all results and build the final array at the end\n const totalSelections = selections.length\n return from(selectionChunks).pipe(\n mergeMap(fetchChunk, 10),\n reduce((merged: (Record<string, any> | null)[], chunkResults) => {\n chunkResults.forEach((result, idx) => {\n if (result !== null && result !== undefined) merged[idx] = result\n })\n return merged\n }, new Array(totalSelections).fill(null)),\n )\n }\n }\n const batchFetchersCache = new Map()\n function getBatchFetchersForPerspective(perspective?: StackablePerspective[], variant?: string) {\n const key = getPerspectiveCacheKey(perspective, variant)\n if (batchFetchersCache.has(key)) {\n return batchFetchersCache.get(key)\n }\n const batchFetchers = {\n fast: debounceCollect(\n fetchAllDocumentPathsWith(currentDatasetClient, perspective, variant),\n 100,\n ),\n slow: debounceCollect(\n fetchAllDocumentPathsWith(currentDatasetClient, perspective, variant),\n 1000,\n ),\n }\n batchFetchersCache.set(key, batchFetchers)\n return batchFetchers\n }\n\n function currentDatasetListenFields(\n documentId: Id,\n fields: FieldName[],\n perspective?: StackablePerspective[],\n variant?: string,\n ) {\n const {fast: fetchDocumentPathsFast, slow: fetchDocumentPathsSlow} =\n getBatchFetchersForPerspective(perspective, variant)\n\n const hasPerspective = perspective && perspective.length > 0\n /**\n * Q: Why are we using published id if perspective is provided?\n * A: Normally, queries for fetching preview values will be based on the _id of the document,\n * for example `*[_id == \"drafts.foo\"]`. However, if a perspective passed, the query\n * `*[_id == \"drafts.foo\"]` will not match anything since the `_id` will always be the published id\n * Therefore, if perspective is provided, we need to refetch using the published id instead.\n */\n const fetchId = hasPerspective ? getPublishedId(documentId) : documentId\n\n return invalidationChannel.pipe(\n filter((event) => {\n // we always want to fetch when the listener just (re) connected\n if (event.type === 'connected') {\n return true\n }\n if (hasPerspective) {\n // With perspectives, refetch only when the mutated document is a\n // version of the observed document (same base/published id) AND that\n // version is relevant to the current perspective stack (e.g. drafts,\n // a specific release). This avoids refetching for unrelated documents\n // or versions outside the active perspective.\n if (getPublishedId(event.documentId) !== getPublishedId(documentId)) {\n return false\n }\n // Variant documents are `versions.<opaqueScopeId>.<groupId>`, and scope ids never appear\n // in the perspective stack, so the stack check can't recognise them. Under a variant\n // selection, any mutation within the document group is treated as relevant.\n return Boolean(variant) || idMatchesPerspective(perspective, event.documentId)\n }\n // if not using perspective, refetch previews for the document that was actually changed\n return event.documentId === documentId\n }),\n switchMap((event) => {\n if (event.type === 'connected' || event.visibility === 'query') {\n return fetchDocumentPathsFast(fetchId, fields).pipe(\n mergeMap((result) => {\n return concat(\n of(result),\n result === null // hack: if we get undefined as result here it can be because the document has\n ? // just been created and is not yet indexed. We therefore need to wait a bit\n // and then re-fetch.\n fetchDocumentPathsSlow(fetchId, fields)\n : [],\n )\n }),\n )\n }\n return fetchDocumentPathsSlow(fetchId, fields)\n }),\n )\n }\n\n const CACHE: Cache = {} // todo: use a LRU cache instead (e.g. hashlru or quick-lru)\n\n const getBatchFetcherForDataset = memoize(\n function getBatchFetcherForDataset(apiConfig: ApiConfig) {\n const client = currentDatasetClient.withConfig(apiConfig)\n const fetchAll = fetchAllDocumentPathsWith(client, ['drafts'])\n return debounceCollect(fetchAll, 10)\n },\n (apiConfig) => apiConfig.dataset + apiConfig.projectId,\n )\n\n const CROSS_DATASET_PREVIEW_POLL_INTERVAL = 10000\n // We want to poll for changes in the other dataset, but only when window/tab is visible\n // This sets up a shared stream that emits an event every `POLL_INTERVAL` milliseconds as long as the\n // document is visible. It starts emitting immediately (if the page is visible)\n const visiblePoll$ = fromEvent(document, 'visibilitychange').pipe(\n startWith(0),\n map(() => document.visibilityState === 'visible'),\n switchMap((visible) => (visible ? timer(0, CROSS_DATASET_PREVIEW_POLL_INTERVAL) : EMPTY)),\n share(),\n )\n\n function crossDatasetListenFields(id: Id, fields: FieldName[], apiConfig: ApiConfig) {\n return visiblePoll$.pipe(startWith(0)).pipe(\n switchMap(() => {\n const batchFetcher = getBatchFetcherForDataset(apiConfig)\n return batchFetcher(id, fields)\n }),\n )\n }\n\n function createCachedFieldObserver<T>(\n id: string,\n fields: FieldName[],\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ): CachedFieldObserver {\n // Note: `undefined` means the memo has not been set, while `null` means the memo is explicitly set to null (e.g. we did fetch, but got null back)\n let latest: T | undefined | null\n const changes$ = merge(\n defer(() => (latest === undefined ? EMPTY : of(latest))),\n (apiConfig\n ? (crossDatasetListenFields(id, fields, apiConfig) as any)\n : currentDatasetListenFields(id, fields, perspective, variant)) as Observable<T>,\n ).pipe(\n tap((v: T | null) => (latest = v)),\n shareReplay({refCount: true, bufferSize: 1}),\n )\n\n return {id, fields, changes$}\n }\n\n function cachedObserveFields(\n id: Id,\n fields: FieldName[],\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ) {\n const cacheKey = apiConfig\n ? `${apiConfig.projectId}:${apiConfig.dataset}:${id}`\n : `$current$-${id}-${getPerspectiveCacheKey(perspective, variant)}`\n\n if (!(cacheKey in CACHE)) {\n CACHE[cacheKey] = []\n }\n\n const existingObservers = CACHE[cacheKey]\n const missingFields = difference(\n fields,\n flatten(existingObservers.map((cachedFieldObserver) => cachedFieldObserver.fields)),\n )\n\n if (missingFields.length > 0) {\n existingObservers.push(createCachedFieldObserver(id, fields, apiConfig, perspective, variant))\n }\n\n const cachedFieldObservers = existingObservers\n .filter((observer) => observer.fields.some((fieldName) => fields.includes(fieldName)))\n .map((cached) => cached.changes$)\n\n return combineLatest(cachedFieldObservers).pipe(\n // in the event that a document gets deleted, the cached values will be updated to store `undefined`\n // if this happens, we should not pick any fields from it, but rather just return null\n map((snapshots) => snapshots.filter(Boolean)), // make sure all snapshots agree on same revision\n filter((snapshots) => isUniqueBy(snapshots, (snapshot) => snapshot._rev)), // pass on value with the requested fields (or null if value is deleted)\n map((snapshots) => (snapshots.length === 0 ? null : pickFrom(snapshots, fields))), // emit values only if changed\n distinctUntilChanged(hasEqualFields(fields)),\n )\n }\n\n return cachedObserveFields\n\n function pickFrom(objects: Record<string, any>[], fields: string[]) {\n return [...INCLUDE_FIELDS, ...fields].reduce((result, fieldName) => {\n const value = getFirstFieldValue(objects, fieldName)\n if (value !== undefined) {\n ;(result as any)[fieldName] = value\n }\n return result\n }, {})\n }\n\n function getFirstFieldValue(objects: Record<string, any>[], fieldName: string) {\n let value\n objects.some((object) => {\n if (fieldName in object) {\n value = object[fieldName]\n return true\n }\n return false\n })\n return value\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {dequal as isEqual} from 'dequal/lite'\nimport {concat, from, type Observable, of, type OperatorFunction, retry, Subject, timer} from 'rxjs'\nimport {\n bufferWhen,\n distinctUntilChanged,\n filter,\n finalize,\n map,\n mergeMap,\n shareReplay,\n switchMap,\n tap,\n toArray,\n} from 'rxjs/operators'\n\nimport {RELEASES_STUDIO_CLIENT_OPTIONS} from '../releases/util/releasesClient'\nimport {versionedClient} from '../studioClient'\nimport {MAX_DOCUMENT_ID_CHUNK_SIZE} from '../util/const'\nimport {getPublishedId} from '../util/draftUtils'\nimport {type InvalidationChannelEvent} from './types'\nimport {debounceCollect} from './utils/debounceCollect'\n\n/**\n * Approximate per-id overhead of a single document group member subquery.\n */\nconst VERSION_OF_QUERY_OVERHEAD = '*[sanity::versionOf(\"\")]._id,'.length\n\n/**\n * Maximum number of batch queries to keep in flight at once.\n */\nconst MAX_CONCURRENT_BATCH_FETCHES = 10\n\n/**\n * Create a function that observes the set of version and variant document ids\n * that exist for the provided document group id.\n *\n * Unlike `createDocumentIdSetObserver`, which opens a dedicated listener for\n * each document group id, this observer is driven by the shared global\n * `invalidationChannel`. It condenses the queries for all observed document\n * group ids into a single GROQ query (one `sanity::versionOf()` call per id),\n * batching the request if it exceeds `MAX_DOCUMENT_ID_BATCH_SIZE`.\n *\n * @internal\n */\nexport function createObserveVersionDocumentIds(options: {\n client: SanityClient\n invalidationChannel: Observable<InvalidationChannelEvent>\n}): (documentGroupId: string) => Observable<string[]> {\n const {client, invalidationChannel} = options\n const releasesClient = versionedClient(client, RELEASES_STUDIO_CLIENT_OPTIONS.apiVersion)\n\n const fetchFast = debounceCollect(\n (collectedArgs: [documentGroupId: string][]) =>\n fetchVersionIdSets(releasesClient, collectedArgs),\n 100,\n )\n\n const fetchSlow = debounceCollect(\n (collectedArgs: [documentGroupId: string][]) =>\n fetchVersionIdSets(releasesClient, collectedArgs),\n 1000,\n )\n\n const cache = new Map<string, Observable<string[]>>()\n\n return function observeVersionDocumentIds(documentGroupId: string): Observable<string[]> {\n const cachedInstance = cache.get(documentGroupId)\n\n if (cachedInstance) {\n return cachedInstance\n }\n\n const instance = invalidationChannel.pipe(\n filter(\n (event) =>\n event.type === 'connected' || getPublishedId(event.documentId) === documentGroupId,\n ),\n switchMap((event) => {\n if (event.type === 'connected' || event.visibility === 'query') {\n return fetchFast(documentGroupId).pipe(\n mergeMap((ids) => {\n // A newly created version may not be indexed yet when its mutation\n // event arrives. If the mutated document isn't reflected in the\n // fresh result, schedule a slow refetch to catch up (mirroring the\n // fast/slow fallback in `observeFields`).\n const maybeIndexPending =\n event.type === 'mutation' &&\n event.documentId !== documentGroupId &&\n !ids.includes(event.documentId)\n\n if (maybeIndexPending) {\n return concat(of(ids), fetchSlow(documentGroupId))\n }\n\n return of(ids)\n }),\n )\n }\n return fetchSlow(documentGroupId)\n }),\n distinctUntilChanged(isEqual),\n finalize(() => cache.delete(documentGroupId)),\n shareReplay({\n refCount: true,\n bufferSize: 1,\n }),\n )\n\n cache.set(documentGroupId, instance)\n return instance\n }\n}\n\n/**\n * Buffer source values into batches, closing the current batch just before a\n * value would push its cumulative byte size to or beyond `maxBytes`. The\n * overflowing value becomes the first entry of the next batch; a value whose\n * own size already meets the limit is emitted as a single-element batch.\n *\n * @internal\n */\nexport function bufferByByteSize<Type extends string>(\n byteSize: (value: Type) => number,\n maxBytes: number,\n): OperatorFunction<Type, Type[]> {\n return (source) => {\n const closeBuffer = new Subject<void>()\n let bufferedBytes = 0\n\n return source.pipe(\n tap((value) => {\n const size = byteSize(value)\n // Close the current (non-empty) buffer before this value would exceed\n // the limit, so the overflowing value becomes the first entry of the\n // next buffer instead.\n if (bufferedBytes > 0 && bufferedBytes + size >= maxBytes) {\n bufferedBytes = 0\n closeBuffer.next()\n }\n bufferedBytes += size\n }),\n bufferWhen(() => closeBuffer),\n )\n }\n}\n\nfunction buildQuery(documentGroupIds: string[]): string {\n const subQueries = documentGroupIds.map((id) => `*[sanity::versionOf(${JSON.stringify(id)})]._id`)\n return `[${subQueries.join(',')}]`\n}\n\nfunction fetchBatch(client: SanityClient, ids: string[]): Observable<string[][]> {\n return client.observable\n .fetch<string[][]>(buildQuery(ids), {}, {tag: 'preview.observe-version-ids'})\n .pipe(\n retry({delay: (_: unknown, attempt) => timer(Math.min(30_000, attempt * 1000))}),\n // Sort each set ascending so consumers get a stable order.\n map((result) => result.map((versionIds) => [...versionIds].sort())),\n )\n}\n\nfunction fetchVersionIdSets(\n client: SanityClient,\n collectedArgs: [documentGroupIds: string][],\n): Observable<string[][]> {\n const documentGroupIds = collectedArgs.map(([documentGroupId]) => documentGroupId)\n\n if (documentGroupIds.length === 0) {\n return of([])\n }\n\n return from(documentGroupIds).pipe(\n // Split into batches small enough that each combined query stays within the\n // max query size.\n bufferByByteSize((id) => id.length + VERSION_OF_QUERY_OVERHEAD, MAX_DOCUMENT_ID_CHUNK_SIZE),\n // Fetch batches in parallel, tracking each batch's position so results can\n // be reordered.\n mergeMap(\n (batch, index) => fetchBatch(client, batch).pipe(map((result) => ({index, result}))),\n MAX_CONCURRENT_BATCH_FETCHES,\n ),\n toArray(),\n // Restore source order (parallel fetches may settle out of order), and\n // flatten the batch results back into a single array aligned with\n // `documentGroupIds`.\n map((settled) => settled.sort((a, b) => a.index - b.index).flatMap(({result}) => result)),\n )\n}\n","import {\n type MutationEvent,\n type QueryParams,\n type SanityClient,\n type StackablePerspective,\n type WelcomeEvent,\n} from '@sanity/client'\nimport {type DocumentSystem, type PrepareViewOptions, type SanityDocument} from '@sanity/types'\nimport {combineLatest, type Observable} from 'rxjs'\nimport {distinctUntilChanged, filter, map} from 'rxjs/operators'\n\nimport {isRecord} from '../util/isRecord'\nimport {\n createDocumentStackAvailabilityObserver,\n createPreviewAvailabilityObserver,\n} from './availability'\nimport {DOCUMENT_SYSTEM_FIELD} from './constants'\nimport {createGlobalListener} from './createGlobalListener'\nimport {createObserveDocument, type ObserveDocumentAPIConfig} from './createObserveDocument'\nimport {createPathObserver} from './createPathObserver'\nimport {createPreviewObserver} from './createPreviewObserver'\nimport {createObservePathsDocumentPair} from './documentPair'\nimport {createDocumentIdSetObserver, type DocumentIdSetObserverState} from './liveDocumentIdSet'\nimport {createObserveFields} from './observeFields'\nimport {createObserveVersionDocumentIds} from './observeVersionDocumentIds'\nimport {\n type ApiConfig,\n type DocumentStackAvailability,\n type DraftsModelDocument,\n type DraftsModelDocumentAvailability,\n type ObservePathsFn,\n type PreparedSnapshot,\n type Previewable,\n type PreviewableType,\n type PreviewPath,\n} from './types'\n\n/**\n * @hidden\n * @beta */\nexport type ObserveForPreviewFn = (\n value: Previewable,\n type: PreviewableType,\n options?: {\n viewOptions?: PrepareViewOptions\n perspective?: StackablePerspective[]\n /**\n * The selected editing variant as a bare variant id. When set, preview values are resolved as\n * seen through that variant, on top of the given perspective.\n */\n variant?: string\n apiConfig?: ApiConfig\n },\n) => Observable<PreparedSnapshot>\n\n/**\n * The document preview store supports subscribing to content for previewing purposes.\n * Documents observed by this store will be kept in sync and receive real-time updates from all collaborators,\n * but has no support for optimistic updates, so any local edits will require a server round-trip before becoming visible,\n * which means this store is less suitable for real-time editing scenarios.\n *\n * @hidden\n * @beta */\nexport interface DocumentPreviewStore {\n observePaths: ObservePathsFn\n observeForPreview: ObserveForPreviewFn\n observeDocumentTypeFromId: (\n id: string,\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ) => Observable<string | undefined>\n observeDocumentSystemFromId: (\n id: string,\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ) => Observable<DocumentSystem | undefined>\n\n /**\n *\n * @hidden\n * @beta\n */\n unstable_observeDocumentPairAvailability: (\n id: string,\n options?: {version?: string},\n ) => Observable<DraftsModelDocumentAvailability>\n\n /**\n *\n * @hidden\n * @beta\n */\n unstable_observeDocumentStackAvailability: (\n id: string,\n perspectiveStack: StackablePerspective[],\n ) => Observable<DocumentStackAvailability[]>\n\n unstable_observePathsDocumentPair: <T extends SanityDocument = SanityDocument>(\n id: string,\n paths: PreviewPath[],\n options?: {version?: string},\n ) => Observable<DraftsModelDocument<T>>\n\n /**\n * Observes a set of document IDs that matches the given groq-filter. The document ids are returned in ascending order and will update in real-time\n * Whenever a document appears or disappears from the set, a new array with the updated set of IDs will be pushed to subscribers.\n * The query is performed once, initially, and thereafter the set of ids are patched based on the `appear` and `disappear`\n * transitions on the received listener events.\n * This provides a lightweight way of subscribing to a list of ids for simple cases where you just want to subscribe to a set of documents ids\n * that matches a particular filter.\n *\n * @hidden\n * @beta\n * @param filter - A groq filter to use for the document set\n * @param params - Parameters to use with the groq filter\n * @param options - Options for the observer\n * @param apiVersion - Specify the API version to use for the query\n */\n unstable_observeDocumentIdSet: (\n filter: string,\n params?: QueryParams,\n options?: {\n /**\n * Where to insert new items into the set. Defaults to 'sorted' which is based on the lexicographic order of the id\n */\n insert?: 'sorted' | 'prepend' | 'append'\n apiVersion?: string\n },\n ) => Observable<DocumentIdSetObserverState>\n\n /**\n * Observes the set of version and variant document ids that exist for a given\n * document group id.\n *\n * Unlike `unstable_observeDocumentIdSet`, this does not open a dedicated\n * real-time listener for each published id. Instead, it is driven by the\n * shared global listener and batches the discovery queries for all observed\n * document group ids into a single combined query, returning the ids in\n * ascending order.\n *\n * @hidden\n * @beta\n */\n unstable_observeVersionDocumentIds: (publishedId: string) => Observable<string[]>\n\n /**\n * Observe a complete document with the given ID\n *\n * @hidden\n * @beta\n */\n unstable_observeDocument: (\n id: string,\n clientConfig?: ObserveDocumentAPIConfig,\n ) => Observable<SanityDocument | undefined>\n\n /**\n * Observe a list of complete documents with the given IDs\n *\n * @hidden\n * @beta\n */\n unstable_observeDocuments: (\n ids: string[],\n clientConfig?: ObserveDocumentAPIConfig,\n ) => Observable<(SanityDocument | undefined)[]>\n}\n\n/** @internal */\nexport interface DocumentPreviewStoreOptions {\n client: SanityClient\n}\n\n/** @internal */\nexport function createDocumentPreviewStore({\n client,\n}: DocumentPreviewStoreOptions): DocumentPreviewStore {\n const versionedClient = client.withConfig({apiVersion: '2025-02-19'})\n const globalListener = createGlobalListener(versionedClient).pipe(\n filter(\n (event): event is MutationEvent | WelcomeEvent =>\n // ignore reconnect events for now until we've verified that downstream consumers can handle them\n event.type === 'mutation' || event.type === 'welcome',\n ),\n )\n const invalidationChannel = globalListener.pipe(\n map((event) => (event.type === 'welcome' ? {type: 'connected' as const} : event)),\n )\n\n const observeDocument = createObserveDocument({client, mutationChannel: globalListener})\n const observeFields = createObserveFields({client: versionedClient, invalidationChannel})\n const observePaths = createPathObserver({observeFields})\n\n function observeDocumentTypeFromId(\n id: string,\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ): Observable<string | undefined> {\n return observePaths(\n {_type: 'reference', _ref: id},\n ['_type'],\n apiConfig,\n perspective,\n variant,\n ).pipe(\n map((res) => (isRecord(res) && typeof res._type === 'string' ? res._type : undefined)),\n distinctUntilChanged(),\n )\n }\n function observeDocumentSystemFromId(\n id: string,\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n // TODO: This shouldn't be undefined once the documents are migrated.\n ): Observable<DocumentSystem | undefined> {\n return observePaths(\n {_type: 'reference', _ref: id},\n [DOCUMENT_SYSTEM_FIELD],\n apiConfig,\n perspective,\n variant,\n ).pipe(\n map((res) =>\n isRecord(res) && isRecord(res[DOCUMENT_SYSTEM_FIELD])\n ? (res[DOCUMENT_SYSTEM_FIELD] as unknown as DocumentSystem)\n : undefined,\n ),\n distinctUntilChanged(),\n )\n }\n\n const observeDocumentIdSet = createDocumentIdSetObserver(versionedClient)\n\n const observeVersionDocumentIds = createObserveVersionDocumentIds({\n client: versionedClient,\n invalidationChannel,\n })\n\n const observeForPreview = createPreviewObserver({observeDocumentTypeFromId, observePaths})\n\n const observeDocumentStackAvailability = createDocumentStackAvailabilityObserver(\n versionedClient,\n observePaths,\n )\n const observeDocumentPairAvailability = createPreviewAvailabilityObserver(\n versionedClient,\n observePaths,\n )\n\n const observePathsDocumentPair = createObservePathsDocumentPair({\n observeDocumentPairAvailability,\n observePaths,\n })\n\n // @todo: explain why the API is like this now, and that it should not be like this in the future!\n\n return {\n observePaths,\n observeForPreview,\n observeDocumentTypeFromId,\n observeDocumentSystemFromId,\n unstable_observeDocumentIdSet: observeDocumentIdSet,\n unstable_observeVersionDocumentIds: observeVersionDocumentIds,\n unstable_observeDocument: observeDocument,\n unstable_observeDocuments: (ids: string[]) =>\n combineLatest(ids.map((id) => observeDocument(id))),\n unstable_observeDocumentPairAvailability: observeDocumentPairAvailability,\n unstable_observeDocumentStackAvailability: observeDocumentStackAvailability,\n unstable_observePathsDocumentPair: observePathsDocumentPair,\n }\n}\n","import {createNode} from '@sanity/comlink'\nimport {type FrameMessages, type WindowMessages} from '@sanity/message-protocol'\n\nimport {type CapabilityRecord} from '../renderingContext/types'\nimport {type ComlinkStore} from './types'\n\ninterface Options {\n capabilities: CapabilityRecord\n}\n\n// These values must match the bindings of the same name exported by `@sanity/message-protocol`.\n// We are currently unable to consume this package at runtime because of ESM issues.\n//\n// TODO: Consume `SDK_CHANNEL_NAME` and `SDK_NODE_NAME` from `@sanity/message-protocol`.\nconst SDK_CHANNEL_NAME = 'dashboard/channels/sdk'\nconst SDK_NODE_NAME = 'dashboard/nodes/sdk'\n\nfunction noop() {}\n\n/**\n * Create a Comlink node if Comlink is provided by the Studio rendering context. The node is not\n * started here — the store is created during render — but by the first `start()` call, which\n * `useComlinkStore` makes once the consumer has committed.\n *\n * @internal\n */\nexport function createComlinkStore({capabilities}: Options): ComlinkStore {\n if (!capabilities.comlink) {\n return {start: noop}\n }\n\n const node = createNode<FrameMessages, WindowMessages>({\n name: SDK_NODE_NAME,\n connectTo: SDK_CHANNEL_NAME,\n })\n\n let started = false\n\n return {\n node,\n start: () => {\n if (started) return\n started = true\n node.start()\n },\n }\n}\n","import {type Observable, type OperatorFunction} from 'rxjs'\nimport {catchError, tap} from 'rxjs/operators'\n\ntype Selector<T, K> = (error: unknown, attemptNo: number, caught: Observable<T>) => Observable<K>\n\n/**\n * Like catchError, but passes the number of successive errors as the second argument to the selector function\n * @internal\n * @hidden\n */\nexport function catchWithCount<T, K = T>(selector: Selector<T, K>): OperatorFunction<T, K>\nexport function catchWithCount<T, K = T>(selector: Selector<T, K>) {\n return (input$: Observable<T>) => {\n let successiveErrorsCount = 0\n\n const errorOp: OperatorFunction<any, any> = catchError(\n (err: unknown, caught: Observable<T>) => {\n successiveErrorsCount++\n return selector(err, successiveErrorsCount, caught).pipe(errorOp)\n },\n )\n return input$.pipe(\n tap(() => {\n // Reset when source stream emits a value (i.e. not errors)\n successiveErrorsCount = 0\n }),\n errorOp,\n )\n }\n}\n","import {type BifurClient} from '@sanity/bifur-client'\nimport {observableCallback} from 'observable-callback'\nimport {concat, fromEvent, merge, NEVER, type Observable, of, throwError, timer} from 'rxjs'\nimport {map, mergeMapTo, startWith, take, takeUntil} from 'rxjs/operators'\n\nimport {catchWithCount} from '../../util/catchWithCount'\n\n/** @internal */\nexport interface ConnectionStatusStore {\n connectionStatus$: Observable<ConnectionStatus>\n}\n\nconst onOnline$ = typeof window === 'undefined' ? of({}) : fromEvent(window, 'online')\nconst onOffline$ = typeof window === 'undefined' ? of({}) : fromEvent(window, 'offline')\n\nconst expBackoff = (retryCount: number) => Math.pow(2, retryCount) * 100\n\n/** @internal */\nexport type ConnectingStatus = {\n type: 'connecting'\n}\n\n/** @internal */\nexport type ErrorStatus = {\n type: 'error'\n error: Error\n attemptNo: number\n isOffline: boolean\n retryAt: Date\n}\n\n/** @internal */\nexport type RetryingStatus = {\n type: 'retrying'\n}\n\n/** @internal */\nexport type ConnectedStatus = {type: 'connected'; lastHeartbeat: Date}\n\n/** @internal */\nexport const CONNECTING: ConnectingStatus = {type: 'connecting'}\n\n/** @internal */\nexport type ConnectionStatus = ConnectingStatus | ErrorStatus | ConnectedStatus | RetryingStatus\n\nconst _callback = observableCallback()\n\nconst onRetry$ = _callback[0]\n\n/** @internal */\nexport const onRetry = _callback[1]\n\nconst createErrorStatus = ({\n error,\n isOffline,\n attemptNo,\n retryAt,\n}: {\n error: Error\n isOffline: boolean\n attemptNo: number\n retryAt: Date\n}): ErrorStatus => ({\n type: 'error',\n error,\n attemptNo,\n isOffline,\n retryAt,\n})\n\n/** @internal */\nexport interface ConnectionStatusStoreOptions {\n bifur: BifurClient\n}\n\n/**\n * This is the beginning of what should be the data store tracking connection status in the Sanity studio.\n *\n * @internal\n */\nexport function createConnectionStatusStore({\n bifur,\n}: ConnectionStatusStoreOptions): ConnectionStatusStore {\n const connectionStatus$: Observable<ConnectionStatus> = merge(\n bifur.heartbeats,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n onOffline$.pipe(mergeMapTo(throwError(new Error('The browser went offline')))),\n ).pipe(\n map((ts): ConnectionStatus => ({type: 'connected', lastHeartbeat: ts})),\n catchWithCount((error, successiveErrorsCount, caught) => {\n const timeUntilRetry = Math.min(1000 * 240, expBackoff(successiveErrorsCount))\n const retryAt = new Date(new Date().getTime() + timeUntilRetry)\n const expiry$ = timer(retryAt)\n const isOffline = !navigator.onLine\n const initialErrorStatus = createErrorStatus({\n error: error as Error,\n retryAt,\n isOffline,\n attemptNo: successiveErrorsCount,\n })\n\n const triggerRetry$ = NEVER.pipe(\n takeUntil(isOffline ? onOnline$ : merge(expiry$, onOnline$, onRetry$)),\n )\n\n return concat(of(initialErrorStatus), triggerRetry$.pipe(take(1)), caught)\n }),\n startWith(CONNECTING),\n )\n\n return {connectionStatus$}\n}\n","import {defineEvent} from '@sanity/telemetry'\n\nexport const DocumentDesynced = defineEvent<{errorName: string}>({\n name: 'Document Desynced',\n version: 1,\n description:\n 'Occurs when a \"hole\" in events from the document pair listener is detected and recovered from.',\n})\n","import {defineEvent} from '@sanity/telemetry'\n\ninterface DocumentPairLoadingMeasuredData {\n /**\n * How long it took to load the document pair\n */\n durationMs: number\n\n /**\n * Whether the document pair was loaded from an in-memory cache\n */\n fromCache: boolean\n\n /**\n * Did we load the published document?\n */\n hasPublished: boolean\n\n /**\n * Did we load the draft document?\n */\n hasDraft: boolean\n\n /**\n * Did we load a version document?\n */\n hasVersion: boolean\n}\n\nexport const DocumentPairLoadingMeasured = defineEvent<DocumentPairLoadingMeasuredData>({\n name: 'Document Pair Load Time Measured',\n version: 1,\n description: 'Time from document pair subscription to first ready snapshot',\n maxSampleRate: 30_000,\n})\n","import {defineEvent} from '@sanity/telemetry'\n\nexport const DocumentRebaseOccurred = defineEvent<{\n remoteMutationCount: number\n localMutationCount: number\n}>({\n name: 'Document Rebase Occurred',\n version: 1,\n description:\n 'A remote mutation arrived while local mutations were pending, requiring a rebase of the optimistic state',\n})\n","import {defineEvent} from '@sanity/telemetry'\n\ntype Samples = {\n latency: number\n transactionId: string\n shard?: string\n}\nexport const HighListenerLatencyOccurred = defineEvent<Samples>({\n name: 'High Listener Latency Detected',\n version: 1,\n description: 'Emits when a high listener latency is detected',\n})\n","import {defineEvent} from '@sanity/telemetry'\n\nexport const MutationPerformanceMeasured = defineEvent<{\n transactionId: string\n debounceMs: number\n apiMs: number\n callbackMs: number\n shard?: string\n}>({\n name: 'Mutation Performance Measured',\n version: 1,\n description:\n 'Timing breakdown for mutation round-trip: debounce, API, and listener callback phases',\n})\n","import {isDraftId, isVersionId} from './draftUtils'\n\n/**\n * Indicates the type of document variant, either `draft`, `version` or `published`.\n * Draft documents are prefixed with `drafts.`.\n * Version documents are prefixed with `versions.<versionName>`\n * The rest are considered published documents.\n * @public\n */\nexport type DocumentVariantType = 'draft' | 'version' | 'published'\n\n/**\n * Takes a document id and returns the variant type for that document\n * If it's a document that starts with `version.` it's a `version` document.\n * If it's a document that starts with `drafts.` it's a `draft` document.\n * Otherwise, it's a `published` document.\n * @public\n * */\nexport function getDocumentVariantType(documentId: string): DocumentVariantType {\n if (isDraftId(documentId)) return 'draft'\n if (isVersionId(documentId)) return 'version'\n return 'published'\n}\n","import {isPortableTextBlock, toPlainText} from '@portabletext/toolkit'\nimport {type DocumentSystem} from '@sanity/types'\n\nimport {type PerspectiveBundle} from '../../perspective/types'\nimport {DOCUMENT_SYSTEM_FIELD} from '../../preview/constants'\nimport {VARIANT_DOCUMENTS_PATH} from '../store/constants'\nimport {type SystemVariant} from '../types'\n\nconst VARIANT_ID_PREFIX = `${VARIANT_DOCUMENTS_PATH}.`\n\n/**\n * Published documents omit `bundleId` on `_system`, but `PerspectiveBundle` also includes the\n * `'published'` literal. Call sites should treat both as published without rewriting the value.\n *\n * @internal\n */\nexport function isPublishedBundleId(bundleId: PerspectiveBundle | undefined): boolean {\n return bundleId === undefined || bundleId === 'published'\n}\n\n/**\n * @internal\n */\nexport function isReleaseBundle(bundleId: PerspectiveBundle | undefined): boolean {\n return !isPublishedBundleId(bundleId) && bundleId !== 'drafts'\n}\n\n/**\n * @internal\n */\nexport function getVariantId(variantDocumentId: string): string {\n return variantDocumentId.startsWith(VARIANT_ID_PREFIX)\n ? variantDocumentId.slice(VARIANT_ID_PREFIX.length)\n : variantDocumentId\n}\n\n/**\n * Returns the short variant id for sticky params from a document's `_system.variant._ref`.\n *\n * @internal\n */\nexport function getVariantIdFromDocument(document: Record<string, unknown>): string | undefined {\n const system = document[DOCUMENT_SYSTEM_FIELD] as DocumentSystem | undefined\n const variantRef = system?.variant?._ref\n\n return variantRef ? getVariantId(variantRef) : undefined\n}\n\n/**\n * @internal\n */\nexport function getVariantTitle(variant: SystemVariant): string {\n const title = variant.metadata?.title\n\n if (typeof title === 'string' && title.trim()) {\n return title\n }\n\n return getVariantId(variant._id)\n}\n\n/**\n * @internal\n */\nexport function getVariantConditionsText(conditions: SystemVariant['conditions']): string {\n return Object.entries(conditions)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ')\n}\n\n/**\n * Decodes router state / URL path segments back to a variant document id.\n *\n * @internal\n */\nexport function decodeVariantIdFromRoute(variantIdRaw: string | undefined): string | undefined {\n if (!variantIdRaw) {\n return undefined\n }\n\n let decoded: string\n\n try {\n decoded = decodeURIComponent(variantIdRaw)\n } catch {\n decoded = variantIdRaw\n }\n\n if (decoded.startsWith(`${VARIANT_ID_PREFIX}`)) {\n return decoded\n }\n\n return `${VARIANT_ID_PREFIX}${decoded}`\n}\n\n/**\n * @internal\n */\nexport function getVariantDescription(variant: SystemVariant): string {\n const description = variant.metadata?.description\n\n if (!Array.isArray(description) || !description.every(isPortableTextBlock)) {\n return ''\n }\n\n return toPlainText(description).trim()\n}\n\n/**\n * @internal\n */\nexport function filterVariantsForSearch(\n variants: SystemVariant[],\n searchTerm: string,\n): SystemVariant[] {\n const normalizedSearchTerm = searchTerm.trim().toLowerCase()\n\n if (!normalizedSearchTerm) {\n return variants\n }\n\n return variants.filter((variant) => {\n const searchableValues = [\n getVariantTitle(variant),\n getVariantId(variant._id),\n ...Object.entries(variant.conditions).flat(),\n ]\n\n return searchableValues.some((value) => value.toLowerCase().includes(normalizedSearchTerm))\n })\n}\n\n/** A filterable condition dimension and the distinct values seen for it across all variants. */\nexport interface ConditionFacet {\n key: string\n values: string[]\n}\n\n/**\n * Derive the filterable facets from every variant's `conditions` key-value pairs: one facet per\n * condition key, with its distinct values. Keys and values are sorted for a stable UI. Because the\n * facets come from the full variant list (not the filtered view), the available options never shrink\n * as filters are applied.\n */\nexport function buildConditionFacets(variants: SystemVariant[]): ConditionFacet[] {\n const valuesByKey = new Map<string, Set<string>>()\n\n for (const variant of variants) {\n for (const [key, value] of Object.entries(variant.conditions)) {\n if (typeof value !== 'string' || value.length === 0) continue\n const values = valuesByKey.get(key) ?? new Set<string>()\n values.add(value)\n valuesByKey.set(key, values)\n }\n }\n\n return Array.from(valuesByKey.entries())\n .map(([key, values]) => ({key, values: Array.from(values).sort((a, b) => a.localeCompare(b))}))\n .sort((a, b) => a.key.localeCompare(b.key))\n}\n\n/**\n * A variant matches when, for every active facet, its value for that condition key is one of the\n * selected values. Selecting several values within one facet is an OR; different facets AND together.\n * An empty selection for a facet imposes no constraint.\n */\nexport function variantMatchesConditionFilters(\n variant: SystemVariant,\n filters: Record<string, string[]>,\n): boolean {\n return Object.entries(filters).every(([key, selectedValues]) => {\n if (selectedValues.length === 0) return true\n const value = variant.conditions[key]\n return typeof value === 'string' && selectedValues.includes(value)\n })\n}\n","import {BufferedDocument, Mutation} from '@sanity/mutator'\nimport {type SanityDocument} from '@sanity/types'\nimport {BehaviorSubject, EMPTY, merge, type Observable, Subject} from 'rxjs'\nimport {\n distinctUntilChanged,\n filter,\n map,\n mergeMapTo,\n publishReplay,\n refCount,\n scan,\n share,\n take,\n tap,\n withLatestFrom,\n} from 'rxjs/operators'\n\nimport {type ListenerEvent} from '../getPairListener'\nimport {type MutationEvent} from '../types'\nimport {\n type DocumentMutationEvent,\n type DocumentRebaseEvent,\n type DocumentRemoteMutationEvent,\n type MutationPayload,\n type RemoteSnapshotEvent,\n type SnapshotEvent,\n} from './types'\n\ninterface MutationAction {\n type: 'mutation'\n mutations: MutationPayload[]\n}\n\ninterface CommitAction {\n type: 'commit'\n}\n\ntype Action = MutationAction | CommitAction\n\n/**\n * Represents \"commit requests\" from the mutator.\n * These are emitted from the BufferedDocument instance's `requestHandler` callback\n *\n * @internal\n */\nexport interface CommitRequest {\n mutation: Mutation\n success: () => void\n failure: (error: Error) => void\n cancel: (error: Error) => void\n /** Timestamp (Date.now()) when the first local mutation in this commit batch was received */\n firstMutationReceivedAt?: number\n}\n\n// BufferedDocument.LOCAL never updates its revision due to its internal consistency checks\n// but we sometimes we need the most current _rev on the document in UI land, e.g.\n// in order to do optimistic locking on the edited document to make sure we publish the document the user\n// actually are looking at, and not the one currently at the server\n// Also - the mutator is not setting _updatedAt on patches applied optimistically or\n// when they are received from server\nconst getUpdatedSnapshot = (bufferedDocument: BufferedDocument) => {\n const LOCAL = bufferedDocument.LOCAL\n const HEAD = bufferedDocument.document.HEAD\n if (!LOCAL) {\n return LOCAL\n }\n\n return {\n ...LOCAL,\n _type: (HEAD || LOCAL)._type,\n _rev: (HEAD || LOCAL)._rev,\n _updatedAt: new Date().toISOString(),\n }\n}\n\nconst toSnapshotEvent = (document: any): SnapshotEvent => ({type: 'snapshot', document})\nconst getDocument = <T extends {document: any}>(event: T): T['document'] => event.document\n\n/** @internal */\n// This is an observable interface for BufferedDocument in an attempt\n// to make it easier to work with the api provided by it\nexport const createObservableBufferedDocument = (listenerEvent$: Observable<ListenerEvent>) => {\n // Incoming local actions (e.g. a request to mutate, a request to commit pending changes, etc.)\n const actions$ = new Subject<Action>()\n\n // Track when the first mutation in a batch arrives (for performance telemetry)\n let firstMutationReceivedAt: number | undefined\n\n // Stream of commit requests. Must be handled by a commit handler\n const consistency$ = new BehaviorSubject<boolean>(true)\n\n // Stream of mutations for this document\n // NOTE: this will *not* include remote mutations received over the listener\n // that has *already* applied locally/optimistically\n const mutations$ = new Subject<DocumentMutationEvent>()\n\n // a stream of rebase events emitted from the mutator\n const rebase$ = new Subject<DocumentRebaseEvent>()\n\n // a stream of remote mutations with effetcs\n const remoteMutations = new Subject<DocumentRemoteMutationEvent>()\n\n const commitRequests = new Subject<CommitRequest>()\n\n const createInitialBufferedDocument = (initialSnapshot: SanityDocument | null) => {\n const bufferedDocument = new BufferedDocument(initialSnapshot)\n bufferedDocument.onMutation = ({mutation, remote}: any) => {\n // this is called after either when:\n // 1) local mutations has been added, optimistically applied and queued for sending\n // 2) remote mutations originating from another client has arrived and been applied\n mutations$.next({\n type: 'mutation',\n document: getUpdatedSnapshot(bufferedDocument) as any,\n mutations: mutation.mutations,\n origin: remote ? 'remote' : 'local',\n })\n }\n bufferedDocument.onRemoteMutation = (mutation: any) => {\n remoteMutations.next({\n type: 'remoteMutation',\n head: bufferedDocument.document.HEAD as any,\n transactionId: mutation.transactionId,\n timestamp: mutation.timestamp,\n author: mutation.identity,\n effects: mutation.effects,\n })\n }\n\n bufferedDocument.onRebase = (edge: any, nextRemoteMutations: any, localMutations: any) => {\n rebase$.next({\n type: 'rebase',\n document: edge,\n remoteMutations: nextRemoteMutations,\n localMutations,\n })\n }\n\n bufferedDocument.onConsistencyChanged = (isConsistent) => {\n if (!isConsistent && firstMutationReceivedAt === undefined) {\n firstMutationReceivedAt = Date.now()\n }\n if (isConsistent) {\n firstMutationReceivedAt = undefined\n }\n consistency$.next(isConsistent)\n }\n\n bufferedDocument.commitHandler = (commitArg: CommitRequest) => {\n const captured = firstMutationReceivedAt\n // Reset so the next commit batch doesn't reuse a stale timestamp\n // from a previous batch when the document stays inconsistent\n firstMutationReceivedAt = undefined\n commitRequests.next({...commitArg, firstMutationReceivedAt: captured})\n }\n\n return bufferedDocument\n }\n\n const currentBufferedDocument$ = listenerEvent$.pipe(\n scan((bufferedDocument: BufferedDocument | null, listenerEvent) => {\n // consider renaming 'snapshot' to initial/welcome\n if (listenerEvent.type === 'snapshot') {\n if (bufferedDocument) {\n // we received a new snapshot and already got an old one. When we receive a snapshot again\n // it is usually because the connection has been down. Attempt to save pending changes (if any)\n void bufferedDocument.commit()\n }\n // mark as consistent when a new snapshot is received\n firstMutationReceivedAt = undefined\n consistency$.next(true)\n return createInitialBufferedDocument(listenerEvent.document || null)\n }\n if (bufferedDocument === null) {\n console.warn(\n 'Ignoring event of type \"%s\" since buffered document has not yet been set up with snapshot',\n listenerEvent.type,\n )\n return null\n }\n return bufferedDocument\n }, null),\n filter(\n <T>(bufferedDocument: T): bufferedDocument is NonNullable<T> => bufferedDocument !== null,\n ),\n distinctUntilChanged(),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n refCount(),\n )\n\n // this is a stream of document snapshots where each new snapshot are emitted after listener mutations\n // has been applied. Since the optimistic patches is not emitted on the mutation$ stream, we need this\n // in order to update the document with a new _rev (and _updatedAt)\n const snapshotAfterSync$ = listenerEvent$.pipe(\n filter((ev): ev is MutationEvent => ev.type === 'mutation'),\n withLatestFrom(currentBufferedDocument$),\n map(([mutationEvent, bufferedDocument]) => {\n bufferedDocument.arrive(new Mutation(mutationEvent))\n return getUpdatedSnapshot(bufferedDocument)\n }),\n )\n\n // this is where the side effects mandated by local actions actually happens\n const actionHandler$ = actions$.pipe(\n withLatestFrom(currentBufferedDocument$),\n tap(([action, bufferedDocument]: [Action, BufferedDocument]) => {\n if (action.type === 'mutation') {\n bufferedDocument.add(new Mutation({mutations: action.mutations}))\n }\n if (action.type === 'commit') {\n void bufferedDocument.commit()\n }\n }),\n // We subscribe to this only for the side effects\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n mergeMapTo(EMPTY),\n share(),\n )\n\n const emitAction = (action: any) => actions$.next(action)\n\n const addMutations = (mutations: MutationPayload[]) => emitAction({type: 'mutation', mutations})\n const addMutation = (mutation: MutationPayload) => addMutations([mutation])\n\n const commit = () => {\n currentBufferedDocument$\n .pipe(\n take(1),\n tap((bufferedDocument) => bufferedDocument.commit()),\n )\n .subscribe()\n }\n\n // A stream of this document's snapshot\n const snapshot$ = merge(\n currentBufferedDocument$.pipe(map((bufferedDocument) => bufferedDocument.LOCAL)),\n mutations$.pipe(map(getDocument)),\n rebase$.pipe(map(getDocument)),\n snapshotAfterSync$,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n ).pipe(map(toSnapshotEvent), publishReplay(1), refCount())\n\n const remoteSnapshot$: Observable<RemoteSnapshotEvent> = merge(\n currentBufferedDocument$.pipe(\n map((bufferedDocument) => bufferedDocument.document.HEAD as any),\n map(toSnapshotEvent),\n ),\n remoteMutations,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n ).pipe(publishReplay(1), refCount())\n\n return {\n updates$: merge(snapshot$, actionHandler$, mutations$, rebase$),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n consistency$: consistency$.pipe(distinctUntilChanged(), publishReplay(1), refCount()),\n remoteSnapshot$,\n commitRequest$: commitRequests,\n addMutation,\n addMutations,\n commit,\n }\n}\n","import {type SanityDocument} from '@sanity/types'\nimport {type Observable} from 'rxjs'\n\nimport {type ListenerEvent} from '../getPairListener'\nimport {\n type CommitRequest,\n createObservableBufferedDocument,\n} from './createObservableBufferedDocument'\nimport {\n type CommittedEvent,\n type DocumentMutationEvent,\n type DocumentRebaseEvent,\n type MutationPayload,\n type RemoteSnapshotEvent,\n type SnapshotEvent,\n} from './types'\n\n/**\n * @hidden\n * @beta */\nexport type BufferedDocumentEvent =\n | SnapshotEvent\n | DocumentRebaseEvent\n | DocumentMutationEvent\n | CommittedEvent\n\nconst prepare = (id: string) => (document: Partial<SanityDocument>) => {\n const {_id, _rev, _updatedAt, ...rest} = document\n return {_id: id, ...rest}\n}\n\n/** @internal */\nexport interface BufferedDocumentWrapper {\n consistency$: Observable<boolean>\n remoteSnapshot$: Observable<RemoteSnapshotEvent>\n events: Observable<BufferedDocumentEvent>\n commitRequest$: Observable<CommitRequest>\n // helper functions\n patch: (patches: any[]) => MutationPayload[]\n create: (document: Partial<SanityDocument>) => MutationPayload\n createIfNotExists: (document: SanityDocument) => MutationPayload\n createOrReplace: (document: SanityDocument) => MutationPayload\n delete: () => MutationPayload\n\n mutate: (mutations: MutationPayload[]) => void\n commit: () => void\n}\n\n/** @internal */\nexport const createBufferedDocument = (\n documentId: string,\n // consider naming it remoteEvent$\n listenerEvent$: Observable<ListenerEvent>,\n): BufferedDocumentWrapper => {\n const bufferedDocument = createObservableBufferedDocument(listenerEvent$)\n\n const prepareDoc = prepare(documentId)\n\n const DELETE = {delete: {id: documentId}}\n\n return {\n events: bufferedDocument.updates$,\n consistency$: bufferedDocument.consistency$,\n remoteSnapshot$: bufferedDocument.remoteSnapshot$,\n commitRequest$: bufferedDocument.commitRequest$,\n\n patch: (patches) => patches.map((patch) => ({patch: {...patch, id: documentId}})),\n create: (document) => ({create: prepareDoc(document)}),\n createIfNotExists: (document) => ({createIfNotExists: prepareDoc(document)}),\n createOrReplace: (document) => ({createOrReplace: prepareDoc(document)}),\n delete: () => DELETE,\n\n mutate: (mutations: MutationPayload[]) => bufferedDocument.addMutations(mutations),\n commit: () => bufferedDocument.commit(),\n }\n}\n","import {createDebug} from 'obug'\n\nexport const debug = createDebug('sanity:document-store')\n","import {TTLCache} from '@isaacs/ttlcache'\nimport {type MonoTypeOperatorFunction, type Observable} from 'rxjs'\nimport {mergeMap, scan} from 'rxjs/operators'\n\nimport {debug} from '../debug'\nimport {type ListenerEvent} from '../getPairListener'\n\nconst DEFAULT_TTL = 120_000\nconst DEFAULT_MAX_ENTRIES = 1000\n\nexport function dedupeListenerEvents<T extends ListenerEvent>({\n ttl = DEFAULT_TTL,\n max = DEFAULT_MAX_ENTRIES,\n}: {\n ttl?: number\n max?: number\n} = {}): MonoTypeOperatorFunction<T> {\n return (input$: Observable<T>) =>\n input$.pipe(\n scan(\n ({seen}: {emit: T[]; seen: TTLCache<string, null>}, event: T) => {\n if (event.type !== 'mutation') {\n return {emit: [event], seen}\n }\n const key = `${event.transactionId}#${event.documentId}`\n if (seen.has(key)) {\n debug('Ignoring duplicate listener event: ', key)\n return {seen, emit: []}\n }\n seen.set(key, null)\n return {seen, emit: [event]}\n },\n {emit: [], seen: new TTLCache<string, null>({ttl, max})},\n ),\n mergeMap(\n (state) =>\n // note: if state.emit is an empty array, nothing will be emitted\n state.emit,\n ),\n )\n}\n","import {type MutationEvent} from '../types'\n\nexport function discardChainTo(chain: MutationEvent[], revision: string | undefined) {\n const revisionIndex = chain.findIndex((event) => event.resultRev === revision)\n\n return split(chain, revisionIndex + 1)\n}\n\nfunction split<T>(array: T[], index: number) {\n if (index < 0) {\n return [[], array]\n }\n return [array.slice(0, index), array.slice(index)]\n}\n\nexport function toOrderedChains<T extends {previousRev: string; resultRev: string}>(events: T[]) {\n const parents: Record<string, T | undefined> = {}\n\n events.forEach((event) => {\n parents[event.resultRev] = events.find((other) => other.resultRev === event.previousRev)\n })\n\n // get entries without a parent (if there's more than one, we have a problem)\n const orphans = Object.entries(parents).filter(([, parent]) => {\n return !parent\n })\n\n return orphans.map((orphan) => {\n const [headRev] = orphan\n\n let current = events.find((event) => event.resultRev === headRev)\n\n const sortedList: T[] = []\n while (current) {\n sortedList.push(current)\n current = events.find((event) => event.previousRev === current?.resultRev)\n }\n return sortedList\n })\n}\n","import partition from 'lodash-es/partition.js'\nimport {concat, type Observable, of, switchMap, throwError, timer} from 'rxjs'\nimport {mergeMap, scan} from 'rxjs/operators'\n\nimport {debug} from '../debug'\nimport {type ListenerEvent} from '../getPairListener'\nimport {type MutationEvent} from '../types'\nimport {discardChainTo, toOrderedChains} from './eventChainUtils'\n\ninterface ListenerSequenceState {\n /**\n * Tracks the latest revision from the server that can be applied locally\n * Once we receive a mutation event that has a `previousRev` that equals `base.revision`\n * we will move `base.revision` to the event's `resultRev`\n * `base.revision` will be undefined if document doesn't exist.\n * `base` is `undefined` until the snapshot event is received\n */\n base: {revision: string | undefined} | undefined\n /**\n * Array of events to pass on to the stream, e.g. when mutation applies to current head revision, or a chain is complete\n */\n emitEvents: ListenerEvent[]\n /**\n * Buffer to keep track of events that doesn't line up in a [previousRev, resultRev] -- [previousRev, resultRev] sequence\n * This can happen if events arrive out of order, or if an event in the middle for some reason gets lost\n */\n buffer: MutationEvent[]\n}\n\nconst DEFAULT_MAX_BUFFER_SIZE = 20\nconst DEFAULT_DEADLINE_MS = 30000\n\nconst EMPTY_ARRAY: never[] = []\n\n/**\n * Takes an input observable of listener events that might arrive out of order, and emits them in sequence\n * If we receive mutation events that doesn't line up in [previousRev, resultRev] pairs we'll put them in a buffer and\n * check if we have an unbroken chain every time we receive a new event\n *\n * If the buffer grows beyond `maxBufferSize`, or if `resolveChainDeadline` milliseconds passes before the chain resolves\n * an OutOfSyncError will be thrown on the stream\n *\n * @internal\n */\nexport function sequentializeListenerEvents(options?: {\n maxBufferSize?: number\n resolveChainDeadline?: number\n}) {\n const {resolveChainDeadline = DEFAULT_DEADLINE_MS, maxBufferSize = DEFAULT_MAX_BUFFER_SIZE} =\n options || {}\n\n return (input$: Observable<ListenerEvent>): Observable<ListenerEvent> => {\n return input$.pipe(\n scan(\n (state: ListenerSequenceState, event: ListenerEvent): ListenerSequenceState => {\n if (event.type === 'mutation' && !state.base) {\n throw new Error('Invalid state. Cannot create a sequence without a base')\n }\n if (event.type === 'snapshot') {\n // When receiving a new snapshot, we can safely discard the current orphaned and chainable buffers\n return {\n base: {revision: event.document?._rev},\n buffer: EMPTY_ARRAY,\n emitEvents: [event],\n }\n }\n\n if (event.type === 'mutation') {\n // Note: the buffer may have multiple holes in it (this is a worst case scenario, and probably not likely, but still),\n // so we need to consider all possible chains\n // `toOrderedChains` will return all detected chains and each of the returned chains will be orderered\n // Once we have a list of chains, we can then discard any chain that leads up to the current revision\n // since they are already applied on the document\n const orderedChains = toOrderedChains(state.buffer.concat(event)).map((chain) => {\n // in case the chain leads up to the current revision\n const [discarded, rest] = discardChainTo(chain, state.base!.revision)\n if (discarded.length > 0) {\n debug('Discarded %d mutations already applied to document', discarded.length)\n }\n return rest\n })\n\n const [resolvedChains, _nextBuffer] = partition(orderedChains, (chain) => {\n // note: there can be at most one applicable chain\n return state.base!.revision === chain[0]?.previousRev\n })\n\n const nextBuffer = _nextBuffer\n .flat()\n .toSorted((a, b) => a.messageReceivedAt.localeCompare(b.messageReceivedAt))\n\n if (resolvedChains.length > 1) {\n throw new Error('Expected at most one resolved chain')\n }\n if (resolvedChains.length > 0 && resolvedChains[0].length > 0) {\n // we now have a continuous chain that can apply on the base revision\n // Move current base revision to the last mutation event in the applicable chain\n const lastMutation = resolvedChains[0].at(-1)!\n const nextBaseRevision =\n // special case: if the mutation deletes the document it technically has no revision, despite\n // resultRev pointing at a transaction id.\n lastMutation.transition === 'disappear' ? undefined : lastMutation?.resultRev\n\n if (state.buffer.length > 0) {\n // we went from having unresolved chains to resolved\n debug(\n `Resolved chain: %s => %s`,\n resolvedChains[0][0].previousRev,\n resolvedChains[0].at(-1)?.resultRev,\n )\n if (nextBuffer.length > 0) {\n debug(`There are still %d unchainable mutations`, nextBuffer.length)\n } else {\n debug(`All chains were resolved`)\n }\n }\n return {\n base: {revision: nextBaseRevision},\n emitEvents: resolvedChains[0],\n buffer: nextBuffer,\n }\n }\n\n if (nextBuffer.length >= maxBufferSize) {\n throw new MaxBufferExceededError(\n `Too many unchainable mutation events: ${state.buffer.length}`,\n state,\n )\n }\n return {\n ...state,\n buffer: nextBuffer,\n emitEvents: EMPTY_ARRAY,\n }\n }\n // Any other event (e.g. 'reconnect' is passed on verbatim)\n return {...state, emitEvents: [event]}\n },\n {\n emitEvents: EMPTY_ARRAY,\n base: undefined,\n buffer: EMPTY_ARRAY,\n },\n ),\n switchMap((state) => {\n if (state.buffer.length > 0) {\n // note: buffer is sorted by messageReceivedAt – oldest first\n const brokenChainStartsAt = new Date(state.buffer[0].messageReceivedAt)\n const nextDeadline = resolveChainDeadline - (Date.now() - brokenChainStartsAt.getTime())\n debug(\n \"There are %d listener event(s) that can't be applied in sequence. This could be due to events arriving out of order. Will throw an error if chain can't be resolved within %dms\",\n state.buffer.length,\n nextDeadline,\n )\n debug('Buffered events: %O', state.buffer)\n return concat(\n of(state),\n timer(nextDeadline).pipe(\n mergeMap(() =>\n throwError(() => {\n return new DeadlineExceededError(\n `Did not resolve chain within a deadline of ${resolveChainDeadline}ms`,\n state,\n )\n }),\n ),\n ),\n )\n }\n return of(state)\n }),\n mergeMap((state) => {\n // this will simply flatten the list of events into individual emissions\n // if the flushEvents array is empty, nothing will be emitted\n return state.emitEvents\n }),\n )\n }\n}\n\nexport class OutOfSyncError extends Error {\n /**\n * Attach state to the error for debugging/reporting\n */\n state: ListenerSequenceState\n constructor(message: string, state: ListenerSequenceState) {\n super(message)\n this.name = 'OutOfSyncError'\n this.state = state\n }\n}\n\nexport class DeadlineExceededError extends OutOfSyncError {\n constructor(message: string, state: ListenerSequenceState) {\n super(message, state)\n this.name = 'DeadlineExceededError'\n }\n}\nexport class MaxBufferExceededError extends OutOfSyncError {\n constructor(message: string, state: ListenerSequenceState) {\n super(message, state)\n this.name = 'MaxBufferExceededError'\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type SanityDocument} from '@sanity/types'\nimport groupBy from 'lodash-es/groupBy.js'\nimport {defer, EMPTY, merge, type Observable, of, throwError} from 'rxjs'\nimport {catchError, concatMap, filter, map, mergeMap, scan, share} from 'rxjs/operators'\n\nimport {shareReplayLatest} from '../../preview/utils/shareReplayLatest'\nimport {RELEASES_STUDIO_CLIENT_OPTIONS} from '../../releases/util/releasesClient'\nimport {isConnectionSessionError} from '../../util/apiErrors'\nimport {getVersionFromId} from '../../util/draftUtils'\nimport {type StoreRequestErrorHandler} from '../requestErrorHandler'\nimport {debug} from './debug'\nimport {\n type IdPair,\n type MutationEvent,\n type PendingMutationsEvent,\n type ReconnectEvent,\n type ResetEvent,\n type WelcomeBackEvent,\n type WelcomeEvent,\n} from './types'\nimport {dedupeListenerEvents} from './utils/dedupeListenerEvents'\nimport {OutOfSyncError, sequentializeListenerEvents} from './utils/sequentializeListenerEvents'\n\ninterface Snapshots {\n draft: SanityDocument | null\n published: SanityDocument | null\n version: SanityDocument | null\n}\n\n/** @internal */\nexport interface InitialSnapshotEvent {\n type: 'snapshot'\n documentId: string\n document: SanityDocument | null\n}\n\n/**\n * @internal\n */\nexport interface LatencyReportEvent {\n shard?: string\n latencyMs: number\n transactionId: string\n}\n\n/** @internal */\nexport interface DocumentPairLoadedEvent {\n durationMs: number\n fromCache: boolean\n hasPublished: boolean\n hasDraft: boolean\n hasVersion: boolean\n}\n\n/** @internal */\nexport interface MutationPerformanceEvent {\n transactionId: string\n debounceMs: number\n apiMs: number\n callbackMs: number\n shard?: string\n}\n\n/** @internal */\nexport interface DocumentRebaseTelemetryEvent {\n remoteMutationCount: number\n localMutationCount: number\n}\n\n/** @internal */\nexport interface DocumentStoreExtraOptions {\n tag?: string\n\n /**\n * Optional handler for failures of the initial document snapshot fetch —\n * the only request delegated here. Commit failures are routed through the\n * commit request's own failure/cancel channels, and listener drops\n * recover via reconnects. When omitted, fetch failures propagate to the\n * document event streams.\n */\n snapshotFetchErrorHandler?: StoreRequestErrorHandler\n\n /**\n * Called when we recover from sync error\n * Meant for error tracking / telemetry purposes\n * @param error - the {@link OutOfSyncError} recovered from\n */\n onSyncErrorRecovery?(error: OutOfSyncError): void\n onReportLatency?: (event: LatencyReportEvent) => void\n onSlowCommit?: () => void\n onDocumentPairLoaded?: (event: DocumentPairLoadedEvent) => void\n onReportMutationPerformance?: (event: MutationPerformanceEvent) => void\n onDocumentRebase?: (event: DocumentRebaseTelemetryEvent) => void\n}\n\n/** @internal */\nexport type ListenerEvent =\n | MutationEvent\n | ReconnectEvent\n | InitialSnapshotEvent\n | PendingMutationsEvent\n | WelcomeEvent\n | WelcomeBackEvent\n | ResetEvent\n\nconst PENDING_START: PendingMutationsEvent = {type: 'pending', phase: 'begin'}\nconst PENDING_END: PendingMutationsEvent = {type: 'pending', phase: 'end'}\n\nfunction isMutationEvent(msg: ListenerEvent): msg is MutationEvent {\n return msg.type === 'mutation'\n}\nfunction isMultiTransactionEvent(msg: MutationEvent) {\n return msg.transactionTotalEvents > 1\n}\n\nfunction allPendingTransactionEventsReceived(listenerEvents: ListenerEvent[]) {\n const groupedMutations = groupBy(\n listenerEvents.filter((ev): ev is MutationEvent => ev.type === 'mutation'),\n (e) => e.transactionId,\n )\n // Note: we can't assume that the events come in order, so instead of checking the counter attributes we check that we have actually received all\n return Object.values(groupedMutations).every(\n (mutations) => mutations.length === mutations[0].transactionTotalEvents,\n )\n}\n\n/** @internal */\nexport function getPairListener(\n _client: SanityClient,\n idPair: IdPair,\n options: DocumentStoreExtraOptions = {},\n): Observable<ListenerEvent> {\n const {publishedId, draftId, versionId} = idPair\n const client = idPair.versionId ? _client.withConfig(RELEASES_STUDIO_CLIENT_OPTIONS) : _client\n if (\n (idPair.versionId && getVersionFromId(idPair.versionId) === 'published') ||\n (idPair.versionId && getVersionFromId(idPair.versionId) === 'drafts')\n ) {\n throw new Error('VersionId cannot be \"published\" or \"drafts\"')\n }\n const sharedEvents = defer(() =>\n (\n client.observable.listen(\n `*[_id in $ids]`,\n {\n ids: [publishedId, draftId, versionId].filter((id) => typeof id !== 'undefined'),\n },\n {\n includeResult: false,\n includeAllVersions: true,\n enableResume: true,\n events: ['welcome', 'mutation', 'reconnect', 'reset', 'welcomeback'],\n effectFormat: 'mendoza',\n tag: options.tag || 'document.pair.listen',\n },\n ) as Observable<WelcomeEvent | MutationEvent | ReconnectEvent | WelcomeBackEvent | ResetEvent>\n ).pipe(\n dedupeListenerEvents(),\n map((event): WelcomeEvent | MutationEvent | ReconnectEvent | WelcomeBackEvent | ResetEvent =>\n event.type === 'mutation'\n ? {\n ...event,\n // client equivalent of `event.messageDispatchedAt`\n // note: consider moving this to client.listen()\n messageReceivedAt: new Date().toString(),\n }\n : event,\n ),\n shareReplayLatest({\n predicate: (event) =>\n event.type === 'welcome' ||\n event.type === 'reconnect' ||\n event.type === 'reset' ||\n event.type === 'welcomeback',\n }),\n ),\n )\n\n const pairEvents$ = sharedEvents.pipe(\n concatMap((event) => {\n const shouldSyncDocument =\n event.type === 'reset' ||\n // note: resumability may not be enabled – if so, treat welcome the same way as a reset\n event.type === 'welcome'\n return shouldSyncDocument\n ? fetchInitialDocumentSnapshots().pipe(\n mergeMap(({draft, published, version}) => [\n createSnapshotEvent(draftId, draft),\n createSnapshotEvent(publishedId, published),\n ...(versionId ? [createSnapshotEvent(versionId, version)] : []),\n ]),\n )\n : of(event)\n }),\n scan(\n (\n acc: {\n next: (InitialSnapshotEvent | ListenerEvent | WelcomeEvent)[]\n buffer: (InitialSnapshotEvent | ListenerEvent | WelcomeEvent)[]\n },\n msg,\n ) => {\n // we only care about mutation events\n if (!isMutationEvent(msg)) {\n return {next: [msg], buffer: []}\n }\n\n const isBuffering = acc.buffer.length > 0\n const isMulti = isMultiTransactionEvent(msg)\n if (!isMulti && !isBuffering) {\n // simple case, we have no buffer, and the event is a single-transaction event, so just pass it on\n return {next: [msg], buffer: []}\n }\n\n if (!isMulti) {\n // we have received a single transaction event while waiting for the rest of events from a multi transaction\n // put it in the buffer\n return {next: [], buffer: acc.buffer.concat(msg)}\n }\n\n const nextBuffer = acc.buffer.concat(msg)\n if (allPendingTransactionEventsReceived(nextBuffer)) {\n // we have received all pending transactions, emit the buffer, and signal end of buffer\n return {next: nextBuffer.concat(PENDING_END), buffer: []}\n }\n // if we get here, we are still waiting for more multi-transaction messages\n // if nextBuffer only has one element, we know we just started buffering\n return {next: nextBuffer.length === 1 ? [PENDING_START] : [], buffer: nextBuffer}\n },\n {next: [], buffer: []},\n ),\n // note: this flattens the array, and in the case of an empty array, no event will be pushed downstream\n mergeMap((v) => v.next),\n share(),\n )\n\n const draftEvents$ = pairEvents$.pipe(\n filter((event) =>\n event.type === 'mutation' || event.type === 'snapshot' ? event.documentId === draftId : true,\n ),\n sequentializeListenerEvents(),\n )\n\n const publishedEvents$ = pairEvents$.pipe(\n filter((event) =>\n event.type === 'mutation' || event.type === 'snapshot'\n ? event.documentId === publishedId\n : true,\n ),\n sequentializeListenerEvents(),\n )\n\n const versionEvents$ = pairEvents$.pipe(\n filter((event) =>\n event.type === 'mutation' || event.type === 'snapshot'\n ? event.documentId === versionId\n : true,\n ),\n sequentializeListenerEvents(),\n )\n\n return merge(draftEvents$, publishedEvents$, versionEvents$).pipe(\n catchError((err, caught$) => {\n if (err instanceof OutOfSyncError) {\n debug('Recovering from OutOfSyncError: %s', err.name)\n if (typeof options?.onSyncErrorRecovery === 'function') {\n options?.onSyncErrorRecovery(err)\n } else {\n console.error(err)\n }\n // this will retry immediately\n return caught$\n }\n\n // A listener 401 is a dead session (see isConnectionSessionError), so\n // complete the stream rather than rethrow — an errored stream is rethrown\n // by `useSyncObservable` during render and crashes the tool. Forced logout\n // is not triggered here; it's owned by the request handler, which 401s on\n // the ordinary HTTP requests a mounted pane also fires (users, grants, …).\n // The pane keeps its last value (or stays loading if it never got a\n // snapshot) until that logout lands.\n if (isConnectionSessionError(err)) {\n debug('Listener connection rejected (HTTP 401), terminating (invalid session)')\n return EMPTY\n }\n\n return throwError(() => err)\n }),\n )\n\n function fetchInitialDocumentSnapshots(): Observable<Snapshots> {\n const fetchDocuments = () =>\n client.observable.getDocuments<SanityDocument>(\n [publishedId, draftId, versionId].filter((id): id is string => typeof id === 'string'),\n {tag: 'document.pair.fetch'},\n )\n\n // The pair cannot load without these snapshots, and there is no local\n // recovery if the fetch fails — delegate failures to the error handler\n // when one is provided. Retryable: it's an idempotent GET, safe to\n // re-run.\n //\n // While the handler holds a failed fetch for re-run, `pairEvents$`\n // buffers subsequent listener events behind this observable (concatMap)\n // on purpose: they must chain onto the snapshot once it arrives.\n // The buffer stays small — the listener only carries events for this\n // pair's documents — and tearing down the pair drops it.\n return defer(() =>\n options.snapshotFetchErrorHandler\n ? options.snapshotFetchErrorHandler.attempt(fetchDocuments, {retryable: true})\n : fetchDocuments(),\n ).pipe(\n map(([published, draft, version]) => ({\n draft,\n published,\n version,\n })),\n )\n }\n}\n\nfunction createSnapshotEvent(\n documentId: string,\n document: null | SanityDocument,\n): InitialSnapshotEvent {\n return {\n type: 'snapshot',\n documentId,\n document,\n }\n}\n","import {type SanityClient} from '@sanity/client'\n\nimport {RELEASES_STUDIO_CLIENT_OPTIONS} from '../../../../releases/util/releasesClient'\nimport {type IdPair} from '../../types'\n\nconst ACTIONS_API_MINIMUM_VERSION = '2025-02-19'\n\nexport function actionsApiClient(client: SanityClient, idPair: IdPair): SanityClient {\n if (idPair.versionId) {\n // TODO: Remove after API version is stable and support releases\n return client.withConfig(RELEASES_STUDIO_CLIENT_OPTIONS)\n }\n return client.withConfig({\n apiVersion: ACTIONS_API_MINIMUM_VERSION,\n })\n}\n","import {type SanityClient} from '@sanity/client'\n\nimport {RELEASES_STUDIO_CLIENT_OPTIONS} from '../../../../releases/util/releasesClient'\nimport {type IdPair} from '../../types'\n\nexport function operationsApiClient(client: SanityClient, idPair: IdPair): SanityClient {\n if (idPair.versionId) {\n // TODO: Remove after API version is stable and support releases\n return client.withConfig(RELEASES_STUDIO_CLIENT_OPTIONS)\n }\n return client\n}\n","import {\n type Action,\n type MultipleActionResult,\n type SanityClient,\n type SingleMutationResult,\n} from '@sanity/client'\nimport {type Mutation} from '@sanity/mutator'\nimport {type SanityDocument, type SanityDocumentLike} from '@sanity/types'\nimport omit from 'lodash-es/omit.js'\nimport {combineLatest, defer, EMPTY, from, merge, type Observable, of, timer} from 'rxjs'\nimport {\n catchError,\n distinctUntilChanged,\n filter,\n map,\n mergeMap,\n scan,\n share,\n shareReplay,\n startWith,\n switchMap,\n takeUntil,\n tap,\n withLatestFrom,\n} from 'rxjs/operators'\n\nimport {isInvalidSessionError} from '../../../util/apiErrors'\nimport {type DocumentVariantType} from '../../../util/getDocumentVariantType'\nimport {getVariantId} from '../../../variants/tool/util'\nimport {\n type BufferedDocumentEvent,\n createBufferedDocument,\n} from '../buffered-doc/createBufferedDocument'\nimport {type CommitRequest} from '../buffered-doc/createObservableBufferedDocument'\nimport {\n type DocumentRebaseEvent,\n type MutationPayload,\n type RemoteSnapshotEvent,\n} from '../buffered-doc/types'\nimport {\n type DocumentStoreExtraOptions,\n getPairListener,\n type InitialSnapshotEvent,\n type LatencyReportEvent,\n type ListenerEvent,\n type MutationPerformanceEvent,\n} from '../getPairListener'\nimport {\n type IdPair,\n type MutationEvent,\n type PendingMutationsEvent,\n type ReconnectEvent,\n type ResetEvent,\n type WelcomeBackEvent,\n type WelcomeEvent,\n} from '../types'\nimport {actionsApiClient} from './utils/actionsApiClient'\nimport {operationsApiClient} from './utils/operationsApiClient'\n\n/** Timeout on request that fetches shard name before reporting latency */\nconst FETCH_SHARD_TIMEOUT = 20_000\n\n/** TTL for unmatched entries in the latency tracking pending array */\nconst PENDING_ENTRY_TTL = 60_000\n\n/** Duration after which a commit is considered slow and a warning is surfaced to the user */\nconst SLOW_COMMIT_TIMEOUT_MS = 50_000\n\nconst isMutationEventForDocId =\n (id: string) =>\n (event: ListenerEvent): event is MutationEvent | InitialSnapshotEvent => {\n return (event.type === 'snapshot' || event.type === 'mutation') && event.documentId === id\n }\n\n/**\n * @hidden\n * @beta */\nexport type WithVersion<T> = T & {version: DocumentVariantType}\n\n/**\n * @hidden\n * @beta */\nexport type DocumentVersionEvent = WithVersion<\n ReconnectEvent | BufferedDocumentEvent | WelcomeEvent | WelcomeBackEvent | ResetEvent\n>\n\n/**\n * @hidden\n * @beta */\nexport type RemoteSnapshotVersionEvent = WithVersion<RemoteSnapshotEvent>\n\n/**\n * @hidden\n * @beta\n * The SingleMutationResult type from `@sanity/client` doesn't reflect what we get back from POST /mutate\n */\nexport type MutationResult = Omit<SingleMutationResult, 'documentId'>\n\n/**\n * @hidden\n * @beta */\nexport interface DocumentVersion {\n consistency$: Observable<boolean>\n remoteSnapshot$: Observable<RemoteSnapshotVersionEvent>\n events: Observable<DocumentVersionEvent>\n\n patch: (patches: any[]) => MutationPayload[]\n create: (document: Partial<SanityDocument>) => MutationPayload\n createIfNotExists: (document: SanityDocument) => MutationPayload\n createOrReplace: (document: SanityDocument) => MutationPayload\n delete: () => MutationPayload\n\n mutate: (mutations: MutationPayload[]) => void\n commit: () => void\n}\n\n/**\n * The error thrown by the most recent failed commit attempt. Wrapped in an\n * object (rather than emitted raw) because a commit can reject with any\n * thrown value — including `undefined`, which would otherwise be\n * indistinguishable from the healthy state.\n *\n * @internal\n */\nexport type CommitError = {error: unknown}\n\n/**\n * @hidden\n * @beta */\nexport type Pair = {\n /** @internal */\n transactionsPendingEvents$: Observable<PendingMutationsEvent>\n /**\n * The error from the most recent commit attempt while it failed and is\n * being retried by the mutator, or `undefined` while commits are healthy.\n * Resets to `undefined` on the next successful (or terminally cancelled)\n * commit, and when the pair returns to a consistent state — i.e. the\n * buffered edits the failure was about no longer exist. Distinguishes\n * \"commits are failing\" from \"the backlog is merely slow\" — see\n * `useDocumentSyncState`.\n * @internal\n */\n commitError$: Observable<CommitError | undefined>\n published: DocumentVersion\n draft: DocumentVersion\n version?: DocumentVersion\n}\n\nfunction setVersion<T>(version: 'draft' | 'published' | 'version') {\n return (ev: T): T & {version: 'draft' | 'published' | 'version'} => ({...ev, version})\n}\n\nfunction requireId<T extends {_id?: string; _type: string}>(\n value: T,\n): asserts value is T & {_id: string} {\n if (!value._id) {\n throw new Error('Expected document to have an _id')\n }\n}\n\n//if we're patching a published document directly\n//then we're live editing and we should use raw mutations\n//rather than actions\nfunction isLiveEditMutation(mutationParams: Mutation['params'], publishedId: string) {\n const {resultRev, ...mutation} = mutationParams\n const patchTargets: string[] = mutation.mutations.flatMap((mut) => {\n const mutationPayloads = Object.values(mut)\n if (mutationPayloads.length > 1) {\n throw new Error('Did not expect multiple mutations in the same payload')\n }\n return mutationPayloads[0].id || mutationPayloads[0]._id\n })\n return patchTargets.every((target) => target === publishedId)\n}\n\nfunction toActions(idPair: IdPair, mutationParams: Mutation['params']): Action[] {\n const actions = mutationParams.mutations.flatMap<Action>((mutations) => {\n // This action is not always interoperable with the equivalent mutation. It will fail if the\n // published version of the document already exists.\n if (mutations.createIfNotExists) {\n // ignore all createIfNotExists, as these should be covered by the actions api and only be done locally\n return []\n }\n if (mutations.create) {\n // the actions API requires attributes._id to be set, while it's optional in the mutation API\n requireId(mutations.create)\n const createSystem = (mutations.create as SanityDocumentLike)._system\n if (mutations.create._id === idPair.versionId && createSystem?.variant) {\n return {\n actionType: 'sanity.action.document.variant.create',\n publishedId: idPair.publishedId,\n variantId: getVariantId(createSystem.variant._ref),\n document: mutations.create,\n bundleId: createSystem.bundleId,\n }\n }\n return {\n actionType: 'sanity.action.document.create',\n publishedId: idPair.publishedId,\n attributes: mutations.create,\n ifExists: 'fail',\n }\n }\n if (mutations.patch) {\n return {\n actionType: 'sanity.action.document.edit',\n draftId: idPair.versionId ?? idPair.draftId,\n publishedId: idPair.publishedId,\n patch: omit(mutations.patch, 'id'),\n }\n }\n throw new Error('Cannot map mutation to action')\n })\n\n // Empty action invocations are a noop; although Content Lake accepts them, no transaction will\n // be executed, causing Studio to become stuck in a pending state. To prevent this occurring, a\n // fake unset mutation is added whenever an empty set of actions would otherwise be executed.\n if (actions.length === 0) {\n return [\n {\n actionType: 'sanity.action.document.edit',\n draftId: idPair.draftId,\n publishedId: idPair.publishedId,\n patch: {\n unset: ['_empty_action_guard_pseudo_field_'],\n },\n },\n ]\n }\n\n return actions\n}\n\nfunction commitActions(client: SanityClient, idPair: IdPair, mutationParams: Mutation['params']) {\n if (isLiveEditMutation(mutationParams, idPair.publishedId)) {\n return commitMutations(client, idPair, mutationParams)\n }\n\n return actionsApiClient(client, idPair).observable.action(toActions(idPair, mutationParams), {\n tag: 'document.commit',\n transactionId: mutationParams.transactionId,\n })\n}\n\nfunction commitMutations(\n client: SanityClient,\n idPair: IdPair,\n mutationParams: Mutation['params'],\n): Promise<MutationResult> {\n const {resultRev, ...mutation} = mutationParams\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n return operationsApiClient(client, idPair).dataRequest('mutate', mutation, {\n visibility: 'async',\n returnDocuments: false,\n tag: 'document.commit',\n // This makes sure the studio doesn't crash when a draft is crated\n // because someone deleted a referenced document in the target dataset\n skipCrossDatasetReferenceValidation: true,\n })\n}\n\n/**\n * The 4xx statuses we positively know are terminal for a commit: resubmitting\n * the same mutation can never succeed, so the buffered edits are cancelled\n * (rejected + reset to server HEAD) instead of retried. Opt-in by explicit\n * status rather than a blanket 4xx rule, because the buckets have opposite\n * failure modes: wrongly retrying a terminal error leaves the document\n * visibly stalled with the edits preserved (recoverable), while wrongly\n * cancelling a transient error silently destroys the user's work. Statuses\n * not listed here — including transient 4xx like 408/429 and any 4xx we\n * haven't classified — take the conservative retry path.\n *\n * 401 is terminal only for resource-level denials (e.g. a missing grant —\n * some endpoints answer those with 401, not 403). A 401 tagged as an invalid\n * session (`SIO-401-AEX` expired, `SIO-401-ANF` not found) is carved out\n * below: it says nothing about the mutation itself, and re-authenticating\n * can make the retry succeed, so the buffered edits must be preserved\n * rather than wiped mid-edit. The session itself is handled separately by\n * the force-logout flow.\n */\nconst TERMINAL_COMMIT_STATUSES = new Set([400, 401, 402, 403, 404, 409, 410, 412, 413, 422])\n\n/**\n * The result of a single commit attempt. Failures are routed to the mutator\n * (`request.failure` → retry with backoff, `request.cancel` → terminal\n * reset) *before* being emitted here, so this stream doubles as a\n * side-channel for observing commit health without erroring the document\n * event streams.\n */\ntype CommitAttemptResult =\n | {\n type: 'success'\n result: (MultipleActionResult | MutationResult) & {_perfTimings?: PerfTimings}\n }\n | {type: 'failure'; error: unknown}\n | {type: 'cancel'; error: unknown}\n\nfunction submitCommitRequest(\n client: SanityClient,\n idPair: IdPair,\n request: CommitRequest,\n): Observable<CommitAttemptResult> {\n return from(commitActions(client, idPair, request.mutation.params)).pipe(\n tap({\n next: () => request.success(),\n }),\n map((result): CommitAttemptResult => ({type: 'success', result})),\n // A failed commit is reported to the mutator via `request.cancel` /\n // `request.failure` (which rejects the corresponding commit promise so\n // the buffered document can retry/rebase on reconnect). After that, we\n // must NOT let the error propagate down this observable: it feeds\n // `commits$` → `combinedEvents` → the document `events` stream, and an\n // errored events stream is rethrown by `useObservable` (react-rx) when\n // `useEditState` reads it during render, crashing the document pane.\n // Emit the attempt result as a value instead — the failure has already\n // been routed through its proper channel.\n catchError((error) => {\n // A known-terminal client error cancels: the buffered mutations can't\n // succeed by retrying, so the commit is rejected and the buffer reset\n // to server HEAD (see TERMINAL_COMMIT_STATUSES for the rationale).\n // Everything else — 5xx, transient 4xx (408/429), unclassified 4xx,\n // session-expiry 401s, network errors — fails, so the mutator keeps\n // the buffer and retries with backoff.\n // `error` can be any thrown value — guard before using `in`, which\n // throws on primitives.\n const statusCode =\n typeof error === 'object' &&\n error !== null &&\n 'statusCode' in error &&\n typeof error.statusCode === 'number'\n ? error.statusCode\n : undefined\n if (\n statusCode !== undefined &&\n TERMINAL_COMMIT_STATUSES.has(statusCode) &&\n !isInvalidSessionError(error)\n ) {\n request.cancel(error)\n return of<CommitAttemptResult>({type: 'cancel', error})\n }\n request.failure(error)\n return of<CommitAttemptResult>({type: 'failure', error})\n }),\n )\n}\n\ntype PerfTimings = {\n firstMutationReceivedAt?: number\n apiRequestSentAt: number\n apiResponseReceivedAt: number\n}\n\ntype LatencyTrackingEvent = {\n transactionId: string\n submittedAt: Date\n receivedAt: Date\n deltaMs: number\n perfTimings?: PerfTimings\n}\n\ntype LatencyTrackingPendingEntry =\n | {type: 'submit'; transactionId: string; timestamp: Date; perfTimings?: PerfTimings}\n | {type: 'receive'; transactionId: string; timestamp: Date}\n\ntype LatencyTrackingEntry = LatencyTrackingPendingEntry | {type: 'reset'}\n\ntype LatencyTrackingState = {\n pending: LatencyTrackingPendingEntry[]\n event: LatencyTrackingEvent | undefined\n}\n\n/** @internal */\nexport function checkoutPair(\n client: SanityClient,\n idPair: IdPair,\n /**\n * @deprecated does nothing Preserved to avoid breaking changes\n * Will be removed in the next major version.\n */\n _serverActionsEnabled: Observable<boolean> | undefined,\n options: DocumentStoreExtraOptions = {},\n): Pair {\n const {publishedId, draftId, versionId} = idPair\n\n const {\n onReportLatency,\n onSyncErrorRecovery,\n onSlowCommit,\n onReportMutationPerformance,\n onDocumentRebase,\n snapshotFetchErrorHandler,\n tag,\n } = options\n\n const listenerEvents$ = getPairListener(client, idPair, {\n onSyncErrorRecovery,\n tag,\n snapshotFetchErrorHandler,\n }).pipe(share())\n\n const connectionChangeEvents$ = listenerEvents$.pipe(\n filter((ev) => ev.type === 'reconnect' || ev.type === 'welcome' || ev.type === 'welcomeback'),\n )\n\n const draft = createBufferedDocument(\n draftId,\n listenerEvents$.pipe(filter(isMutationEventForDocId(draftId))),\n )\n\n const version =\n typeof versionId === 'undefined'\n ? undefined\n : createBufferedDocument(\n versionId,\n listenerEvents$.pipe(filter(isMutationEventForDocId(versionId))),\n )\n\n const published = createBufferedDocument(\n publishedId,\n listenerEvents$.pipe(filter(isMutationEventForDocId(publishedId))),\n )\n\n // share commit handling between draft and published\n const transactionsPendingEvents$ = listenerEvents$.pipe(\n filter((ev): ev is PendingMutationsEvent => ev.type === 'pending'),\n )\n\n const commitRequests$ = merge(\n draft.commitRequest$,\n published.commitRequest$,\n version ? version.commitRequest$ : EMPTY,\n ).pipe(share())\n\n const commitAttemptResults$ = commitRequests$.pipe(\n mergeMap((commitRequest) => {\n const apiRequestSentAt = Date.now()\n return submitCommitRequest(client, idPair, commitRequest).pipe(\n map((attemptResult): CommitAttemptResult =>\n attemptResult.type === 'success'\n ? {\n ...attemptResult,\n result: {\n ...attemptResult.result,\n _perfTimings: {\n firstMutationReceivedAt: commitRequest.firstMutationReceivedAt,\n apiRequestSentAt,\n apiResponseReceivedAt: Date.now(),\n },\n },\n }\n : attemptResult,\n ),\n )\n }),\n share(),\n )\n\n // The successful commits — failures/cancels have already been routed to the\n // mutator and must not reach the document event streams (see\n // `submitCommitRequest`).\n const commits$ = commitAttemptResults$.pipe(\n filter(\n (attemptResult): attemptResult is Extract<CommitAttemptResult, {type: 'success'}> =>\n attemptResult.type === 'success',\n ),\n map((attemptResult) => attemptResult.result),\n share(),\n )\n\n // Whether every buffered document in the pair is free of pending local\n // mutations — the pair-level version of the per-document `consistency$`.\n const consistent$ = combineLatest([\n draft.consistency$,\n published.consistency$,\n version ? version.consistency$ : of(true),\n ]).pipe(\n map((states) => states.every(Boolean)),\n distinctUntilChanged(),\n )\n\n // The error from the most recent commit attempt while the mutator is\n // retrying it on backoff, `undefined` while commits are healthy. Multicast\n // with replay so late subscribers (the sync-state hook mounts after the\n // pair is checked out) see the current value, not just future attempt\n // results — the silenced merge into `combinedEvents` below keeps it\n // recording for the pair's lifetime.\n const commitError$ = merge(\n commitAttemptResults$.pipe(\n map((attemptResult): CommitError | undefined =>\n attemptResult.type === 'failure' ? {error: attemptResult.error} : undefined,\n ),\n ),\n // Returning to consistency means the buffered edits the failure was\n // about are gone — drained, discarded, or reset to server HEAD by a\n // fresh snapshot — so nothing is being retried anymore. Note this is\n // deliberately NOT keyed on listener reconnects (welcome/welcome-back):\n // a live listener says nothing about commit health, and a reconnect\n // while still unsynced must not mask an ongoing failure.\n consistent$.pipe(\n filter((isConsistent) => isConsistent),\n map(() => undefined),\n ),\n ).pipe(startWith(undefined), distinctUntilChanged(), shareReplay({bufferSize: 1, refCount: true}))\n\n const pendingEnd$ = transactionsPendingEvents$.pipe(filter((ev) => ev.phase === 'end'))\n const commitResolved$ = merge(pendingEnd$, commits$)\n\n // Each new commit request restarts the timer via switchMap.\n // The timer is cancelled when the commit succeeds or pending mutations resolve.\n // Note: a *failed* commit does not emit on `commits$` (failures are filtered\n // out of `commitAttemptResults$` above), so `commitResolved$` does not fire for\n // it — a commit that fails after SLOW_COMMIT_TIMEOUT_MS still triggers\n // `onSlowCommit`. That's intentional: it was slow, and it's now failing.\n const slowCommitWarning$ = onSlowCommit\n ? commitRequests$.pipe(\n switchMap(() => timer(SLOW_COMMIT_TIMEOUT_MS).pipe(takeUntil(commitResolved$))),\n tap(() => onSlowCommit()),\n )\n : EMPTY\n\n const rebaseEvents$ = onDocumentRebase\n ? merge(draft.events, published.events, ...(version ? [version.events] : [])).pipe(\n filter((ev): ev is DocumentRebaseEvent & {type: 'rebase'} => ev.type === 'rebase'),\n tap((ev) => {\n try {\n onDocumentRebase({\n remoteMutationCount: ev.remoteMutations.length,\n localMutationCount: ev.localMutations.length,\n })\n } catch {\n // Telemetry callbacks must never kill the document pipeline\n }\n }),\n )\n : EMPTY\n\n // Note: we're only subscribing to this for the side-effect\n const combinedEvents = defer(() =>\n merge(\n onReportLatency || onReportMutationPerformance\n ? reportLatency({\n commits$: commits$,\n listenerEvents$: listenerEvents$,\n client,\n onReportLatency,\n onReportMutationPerformance,\n })\n : merge(commits$, listenerEvents$),\n slowCommitWarning$,\n rebaseEvents$,\n commitError$,\n ),\n ).pipe(\n mergeMap(() => EMPTY),\n share(),\n )\n\n return {\n transactionsPendingEvents$,\n commitError$,\n draft: {\n ...draft,\n events: merge(combinedEvents, connectionChangeEvents$, draft.events).pipe(\n map(setVersion('draft')),\n ),\n remoteSnapshot$: draft.remoteSnapshot$.pipe(map(setVersion('draft'))),\n },\n ...(typeof version === 'undefined'\n ? {}\n : {\n version: {\n ...version,\n events: merge(combinedEvents, connectionChangeEvents$, version.events).pipe(\n map(setVersion('version')),\n ),\n remoteSnapshot$: version.remoteSnapshot$.pipe(map(setVersion('version'))),\n },\n }),\n published: {\n ...published,\n events: merge(combinedEvents, connectionChangeEvents$, published.events).pipe(\n map(setVersion('published')),\n ),\n remoteSnapshot$: published.remoteSnapshot$.pipe(map(setVersion('published'))),\n },\n }\n}\n\nfunction reportLatency(options: {\n commits$: Observable<(MultipleActionResult | MutationResult) & {_perfTimings?: PerfTimings}>\n listenerEvents$: Observable<ListenerEvent>\n client: SanityClient\n onReportLatency?: (event: LatencyReportEvent) => void\n onReportMutationPerformance?: (event: MutationPerformanceEvent) => void\n}) {\n const {client, commits$, listenerEvents$, onReportLatency, onReportMutationPerformance} = options\n // Note: this request happens once and the result is then cached indefinitely\n let shardInfo: Promise<string | undefined>\n try {\n shardInfo = fetch(client.getUrl(client.getDataUrl('ping')), {\n signal: AbortSignal.timeout(FETCH_SHARD_TIMEOUT),\n })\n .then(async (response) => {\n const shard = response.headers.get('X-Sanity-Shard') || undefined\n\n // The ping response is tiny; consuming it lets the browser finish the\n // H2/H3 stream cleanly and avoids long pending receive/cancel timing.\n await response.arrayBuffer().catch(() => undefined)\n return shard\n })\n .catch(() => undefined)\n } catch {\n shardInfo = Promise.resolve(undefined)\n }\n\n const submittedMutations = commits$.pipe(\n map((ev): LatencyTrackingEntry => ({\n type: 'submit' as const,\n transactionId: ev.transactionId,\n timestamp: new Date(),\n perfTimings: ev._perfTimings,\n })),\n share(),\n )\n\n const receivedMutations = listenerEvents$.pipe(\n filter((ev) => ev.type === 'mutation'),\n map((ev): LatencyTrackingEntry => ({\n type: 'receive' as const,\n transactionId: ev.transactionId,\n timestamp: new Date(),\n })),\n share(),\n )\n\n // Clear pending entries on reconnection to avoid matching stale pre-reconnect\n // submit entries with post-reconnect listener events (which would produce\n // wildly inaccurate latency measurements).\n const reconnectionResets = listenerEvents$.pipe(\n filter((ev) => ev.type === 'reconnect' || ev.type === 'welcome' || ev.type === 'welcomeback'),\n map((): LatencyTrackingEntry => ({type: 'reset'})),\n )\n\n return merge(submittedMutations, receivedMutations, reconnectionResets).pipe(\n scan(\n (state: LatencyTrackingState, event): LatencyTrackingState => {\n if (event.type === 'reset') {\n return {event: undefined, pending: []}\n }\n\n // Evict stale entries to prevent unbounded growth from remote/duplicate mutations\n const now = Date.now()\n const pending = state.pending.filter((e) => now - e.timestamp.getTime() < PENDING_ENTRY_TTL)\n\n const matchingIndex = pending.findIndex(\n (e) => e.transactionId === event.transactionId && e.type !== event.type,\n )\n if (matchingIndex > -1) {\n const matching = pending[matchingIndex]\n const [submitEvent, receiveEvent] =\n matching.type === 'submit' ? [matching, event] : [event, matching]\n return {\n event: {\n transactionId: event.transactionId,\n submittedAt: submitEvent.timestamp,\n receivedAt: receiveEvent.timestamp,\n deltaMs: receiveEvent.timestamp.getTime() - submitEvent.timestamp.getTime(),\n perfTimings: submitEvent.type === 'submit' ? submitEvent.perfTimings : undefined,\n },\n // Remove the matched entry and any other entries with the same transactionId\n // (e.g., duplicate receive events from multi-document transactions)\n pending: pending.filter(\n (e, i) => i !== matchingIndex && e.transactionId !== event.transactionId,\n ),\n }\n }\n return {event: undefined, pending: pending.concat(event)}\n },\n {event: undefined, pending: []},\n ),\n map((state) => state.event),\n filter((event) => !!event),\n withLatestFrom(from(shardInfo).pipe(startWith(undefined))),\n tap(([event, shard]) => {\n try {\n onReportLatency?.({latencyMs: event.deltaMs, shard, transactionId: event.transactionId})\n } catch {\n // Telemetry callbacks must never kill the document pipeline\n }\n\n if (onReportMutationPerformance && event.perfTimings) {\n const {firstMutationReceivedAt, apiRequestSentAt, apiResponseReceivedAt} = event.perfTimings\n const listenerReceivedAt = event.receivedAt.getTime()\n\n if (firstMutationReceivedAt !== undefined) {\n try {\n onReportMutationPerformance({\n transactionId: event.transactionId,\n debounceMs: Math.max(0, apiRequestSentAt - firstMutationReceivedAt),\n apiMs: Math.max(0, apiResponseReceivedAt - apiRequestSentAt),\n // Listener and API response race each other — both are triggered\n // server-side after the mutation is committed. Measure callback from\n // when the request was sent, not when the HTTP response arrived.\n callbackMs: Math.max(0, listenerReceivedAt - apiRequestSentAt),\n shard,\n })\n } catch {\n // Telemetry callbacks must never kill the document pipeline\n }\n }\n }\n }),\n )\n}\n","import {type Observable} from 'rxjs'\n\nexport function memoize<TFunction extends (...args: any[]) => Observable<any>>(\n fn: TFunction,\n keyGen: (...args: Parameters<TFunction>) => string,\n): TFunction {\n const MEMO: {[key: string]: Observable<unknown>} = Object.create(null)\n const memoizedFn = (...args: Parameters<TFunction>): Observable<unknown> => {\n const key = keyGen(...args)\n if (!(key in MEMO)) {\n MEMO[key] = fn(...args)\n }\n return MEMO[key]\n }\n\n return memoizedFn as TFunction\n}\n","import {type SanityClient} from '@sanity/client'\n\n/**\n * Segments identifying the credentialed client an observable is built with:\n * `[token, dataset, projectId]`. Any module-level {@link memoize} of a\n * client-capturing observable MUST include these in its key — keying by\n * project/dataset alone replays a stale-token client after a cross-tab\n * re-login and 401s. Keyed by the token *value* (not the client instance) so\n * sibling clients sharing a token reuse one entry and only a real credential\n * change makes a new one.\n *\n * @internal\n */\nexport function getClientCredentialSegments(client: SanityClient): [string, string, string] {\n const {token, dataset, projectId} = client.config()\n return [token ?? '', dataset ?? '', projectId ?? '']\n}\n\n/**\n * Builds a memo cache key from an ordered list of segments. Segments are joined\n * via `JSON.stringify` rather than a `-` (or any single delimiter): the raw\n * values routinely contain dashes (dataset names like `test-dataset`, document\n * ids, type names), so a plain join lets distinct tuples collide into the same\n * string (`['a-b','c']` and `['a','b-c']` both become `a-b-c`) and reuse the\n * wrong cached observable. The result is an opaque cache key — never parsed or\n * shown to users.\n *\n * @internal\n */\nexport function createMemoKey(segments: readonly (string | undefined)[]): string {\n return JSON.stringify(segments.map((segment) => segment ?? ''))\n}\n","import {type SanityClient} from '@sanity/client'\n\nimport {type IdPair} from '../types'\nimport {createMemoKey, getClientCredentialSegments} from '../utils/memoKey'\n\n// The key must include the credential: the pair captures its client and keeps a\n// listener open, so keying by project/dataset alone would replay a stale-token\n// pair after a re-login and 401 on `/data/listen`. See getClientCredentialSegments.\nexport function memoizeKeyGen(client: SanityClient, idPair: IdPair, typeName: string) {\n return createMemoKey([\n ...getClientCredentialSegments(client),\n idPair.publishedId,\n idPair.versionId,\n typeName,\n ])\n}\n","import {type SanityClient} from '@sanity/client'\nimport {EMPTY, merge, Observable, of, ReplaySubject, share, timer} from 'rxjs'\nimport {mergeMap} from 'rxjs/operators'\n\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {checkoutPair, type Pair} from './checkoutPair'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// How long to keep listener connected for after last unsubscribe.\n// Reduced from 10s to 5s to limit concurrent SSE connections during\n// navigation-heavy sessions. 5s still covers most \"navigate away and back\"\n// patterns while cutting the stale connection window in half.\nconst LISTENER_RESET_DELAY = 5_000\n\nexport const memoizedPair: (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n extraOptions?: DocumentStoreExtraOptions,\n) => Observable<Pair> = memoize(\n (\n client: SanityClient,\n idPair: IdPair,\n _typeName: string,\n pairListenerOptions?: DocumentStoreExtraOptions,\n ): Observable<Pair> => {\n return new Observable<Pair>((subscriber) => {\n const pair = checkoutPair(client, idPair, undefined, pairListenerOptions)\n return merge(\n of(pair),\n // merge in draft, published, and version events to makes sure they receive\n // the events they need for as long as the pair is subscribed to\n pair.draft.events.pipe(mergeMap(() => EMPTY)),\n pair.published.events.pipe(mergeMap(() => EMPTY)),\n pair.version?.events.pipe(mergeMap(() => EMPTY)) ?? EMPTY,\n ).subscribe(subscriber)\n }).pipe(\n share({\n connector: () => new ReplaySubject(1),\n resetOnComplete: true,\n resetOnRefCountZero: () => timer(LISTENER_RESET_DELAY),\n }),\n )\n },\n memoizeKeyGen,\n)\n","import {type SanityClient} from '@sanity/client'\nimport {type Observable} from 'rxjs'\nimport {distinctUntilChanged, shareReplay, switchMap} from 'rxjs/operators'\n\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {type CommitError} from './checkoutPair'\nimport {memoizedPair} from './memoizedPair'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// The error from the most recent commit attempt for the document pair while\n// it failed and is being retried by the mutator, or `undefined` while\n// commits are healthy. Combined with consistency and connection state to\n// distinguish \"commits are failing\" from \"the backlog is merely slow\" — see\n// `useDocumentSyncState`.\nexport const commitErrorStatus: (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n extraOptions?: DocumentStoreExtraOptions,\n) => Observable<CommitError | undefined> = memoize(\n (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n extraOptions?: DocumentStoreExtraOptions,\n ) => {\n return memoizedPair(client, idPair, typeName, extraOptions).pipe(\n switchMap((pair) => pair.commitError$),\n distinctUntilChanged(),\n shareReplay({bufferSize: 1, refCount: true}),\n )\n },\n memoizeKeyGen,\n)\n","import {type SanityClient} from '@sanity/client'\nimport {combineLatest, of, type Observable} from 'rxjs'\nimport {distinctUntilChanged, map, publishReplay, refCount, switchMap} from 'rxjs/operators'\n\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {memoizedPair} from './memoizedPair'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// A stream of all events related to either published or draft, each event comes with a 'target'\n// that specifies which version (draft|published) the event is about\nexport const consistencyStatus: (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n extraOptions?: DocumentStoreExtraOptions,\n) => Observable<boolean> = memoize(\n (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n extraOptions?: DocumentStoreExtraOptions,\n ) => {\n return memoizedPair(client, idPair, typeName, extraOptions).pipe(\n switchMap(({draft, published, version}) =>\n combineLatest([\n draft.consistency$,\n published.consistency$,\n version?.consistency$ ?? of(true),\n ]),\n ),\n map(\n ([draftIsConsistent, publishedIsConsistent, versionIsConsistent]) =>\n draftIsConsistent && publishedIsConsistent && versionIsConsistent,\n ),\n distinctUntilChanged(),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n refCount(),\n )\n },\n memoizeKeyGen,\n)\n","import {type SanityClient} from '@sanity/client'\nimport {EMPTY, merge, type Observable} from 'rxjs'\nimport {switchMap} from 'rxjs/operators'\n\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {type DocumentVersionEvent} from './checkoutPair'\nimport {memoizedPair} from './memoizedPair'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// A stream of all events related to either published or draft, each event comes with a 'target'\n// that specifies which version (draft|published) the event is about\nexport const documentEvents = memoize(\n (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n pairListenerOptions?: DocumentStoreExtraOptions,\n ): Observable<DocumentVersionEvent> => {\n return memoizedPair(client, idPair, typeName, pairListenerOptions).pipe(\n switchMap(({draft, published, version}) =>\n merge(draft.events, published.events, version?.events ?? EMPTY),\n ),\n )\n },\n memoizeKeyGen,\n)\n","import {type SanityClient} from '@sanity/client'\nimport {type SanityDocument} from '@sanity/types'\nimport {type Observable} from 'rxjs'\nimport {filter, map, publishReplay, refCount} from 'rxjs/operators'\n\nimport {type BufferedDocumentEvent} from '../buffered-doc/createBufferedDocument'\nimport {type MutationPayload, type SnapshotEvent} from '../buffered-doc/types'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {\n type IdPair,\n type PendingMutationsEvent,\n type ReconnectEvent,\n type ResetEvent,\n type WelcomeBackEvent,\n type WelcomeEvent,\n} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {type DocumentVersion} from './checkoutPair'\nimport {memoizedPair} from './memoizedPair'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// return true if the event comes with a document snapshot\nfunction isSnapshotEvent(\n event: BufferedDocumentEvent | ReconnectEvent | WelcomeEvent | WelcomeBackEvent | ResetEvent,\n): event is SnapshotEvent & {\n version: 'published' | 'draft'\n} {\n return event.type === 'snapshot'\n}\n\nfunction withSnapshots(pair: DocumentVersion): DocumentVersionSnapshots {\n return {\n snapshots$: pair.events.pipe(\n filter(isSnapshotEvent),\n map((event) => event.document),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n refCount(),\n ),\n\n patch: pair.patch,\n create: pair.create,\n createIfNotExists: pair.createIfNotExists,\n createOrReplace: pair.createOrReplace,\n delete: pair.delete,\n\n mutate: pair.mutate,\n commit: pair.commit,\n }\n}\n\n/** @internal */\nexport interface DocumentVersionSnapshots {\n snapshots$: Observable<SanityDocument>\n\n // helper functions\n patch: (patches: any[]) => MutationPayload[]\n create: (document: any) => MutationPayload\n createIfNotExists: (document: any) => MutationPayload\n createOrReplace: (document: any) => MutationPayload\n delete: () => MutationPayload\n\n mutate: (mutations: MutationPayload[]) => void\n commit: () => void\n}\n\n/** @internal */\ninterface SnapshotPair {\n transactionsPendingEvents$: Observable<PendingMutationsEvent>\n draft: DocumentVersionSnapshots\n published: DocumentVersionSnapshots\n version?: DocumentVersionSnapshots\n}\n\n/** @internal */\nexport const snapshotPair = memoize(\n (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n /**\n * @deprecated does nothing\n * Preserved here to avoid breaking changes\n * Will be removed in the next major version.\n */\n _serverActionsEnabled?: Observable<boolean>,\n pairListenerOptions?: DocumentStoreExtraOptions,\n ): Observable<SnapshotPair> => {\n return memoizedPair(client, idPair, typeName, pairListenerOptions).pipe(\n map(({published, draft, version, transactionsPendingEvents$}): SnapshotPair => {\n return {\n transactionsPendingEvents$,\n published: withSnapshots(published),\n draft: withSnapshots(draft),\n ...(version ? {version: withSnapshots(version)} : {}),\n }\n }),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n refCount(),\n )\n },\n memoizeKeyGen,\n)\n","import {type SanityClient} from '@sanity/client'\nimport {type Schema} from '@sanity/types'\nimport {combineLatest, type Observable} from 'rxjs'\nimport {map, publishReplay, refCount, switchMap} from 'rxjs/operators'\n\nimport {type HistoryStore} from '../../history/createHistoryStore'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {memoizeKeyGen} from './memoizeKeyGen'\nimport {type OperationArgs} from './operations/types'\nimport {snapshotPair} from './snapshotPair'\n\nexport const operationArgs = memoize(\n (\n ctx: {\n client: SanityClient\n historyStore: HistoryStore\n schema: Schema\n pairListenerOptions?: DocumentStoreExtraOptions\n },\n idPair: IdPair,\n typeName: string,\n ): Observable<OperationArgs> => {\n return snapshotPair(ctx.client, idPair, typeName, undefined, ctx.pairListenerOptions).pipe(\n switchMap((versions) =>\n combineLatest([\n versions.draft.snapshots$,\n versions.published.snapshots$,\n ...(typeof versions.version === 'undefined' ? [] : [versions.version.snapshots$]),\n ]).pipe(\n map(([draft, published, version]): OperationArgs => ({\n ...ctx,\n idPair,\n typeName,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n serverActionsEnabled: true,\n snapshots: {\n published,\n draft,\n ...(version\n ? {\n version,\n }\n : {}),\n },\n ...(versions.version\n ? {\n version: versions.version,\n }\n : {}),\n draft: versions.draft,\n published: versions.published,\n })),\n ),\n ),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n refCount(),\n )\n },\n (ctx, idPair, typeName) => {\n return memoizeKeyGen(ctx.client, idPair, typeName)\n },\n)\n","import {type SanityClient} from '@sanity/client'\n\nimport {createMemoKey} from '../utils/memoKey'\n\nexport function getOperationStoreKey(client: SanityClient): string {\n const config = client.config()\n const {projectId, dataset, token} = config\n if (!projectId) {\n throw new Error('Client is missing projectId')\n }\n if (!dataset) {\n throw new Error('Client is missing dataset')\n }\n // Include the token so an operation is routed to the pipeline built on the\n // same credential. This key only needs to agree between the emitter and the\n // pipeline (both call this function) — it does not have to equal the\n // operationEvents memo key. Once operationEvents is memoized per token, a\n // re-login runs a second pipeline; without the token here one emitted\n // operation would match both the fresh and the stale-token pipeline while\n // both are briefly subscribed and execute the mutation twice.\n return createMemoKey([projectId, dataset, token])\n}\n","import {EMPTY} from 'rxjs'\n\nimport {type OperationImpl} from './types'\n\nexport const commit: OperationImpl = {\n disabled: (): false => false,\n execute: ({draft, published, version}) => {\n version?.commit()\n draft.commit()\n published.commit()\n // note: we might be able to connect with the outgoing commit request stream here\n return EMPTY\n },\n}\n","import {type SanityDocument} from '@sanity/types'\n\n/** @internal */\nexport const VARIANT_VERSION_DISABLED = 'VARIANT_VERSION' as const\n\n/** @internal */\nexport type VariantVersionDisabledReason = typeof VARIANT_VERSION_DISABLED\n\n/**\n * Legacy transaction-based operations in `operations/` are not supported for variant-scoped\n * versions. Variant documents route through `serverOperations/` and the variant document actions.\n *\n * @internal\n */\nexport function disabledForVariantVersion(\n version: SanityDocument | null | undefined,\n): VariantVersionDisabledReason | false {\n if (version?._system?.variant?._ref) {\n return VARIANT_VERSION_DISABLED\n }\n return false\n}\n\n/**\n * Corruption tripwire: the base/release document actions must never run against a variant-scoped\n * version. A base publish with a variant version in the `draftId` slot would publish variant\n * content INTO the base published document — data corruption, not a broken button. Operations\n * route variant versions to the variant document actions before reaching the base paths; this\n * assert is insurance that stays correct independently of that routing (e.g. through future\n * refactors or new call sites).\n *\n * @internal\n */\nexport function assertNotVariantVersion(\n version: SanityDocument | null | undefined,\n operationName: string,\n): void {\n if (version?._system?.variant?._ref) {\n throw new Error(\n `Cannot execute the base \"${operationName}\" operation against the variant-scoped version \"${version._id}\": this would write variant content into the base document. This is a bug in the operation routing — please report it.`,\n )\n }\n}\n","import {type Schema} from '@sanity/types'\n\nexport const isLiveEditEnabled = (schema: Schema, typeName: string): boolean =>\n schema.get(typeName)?.liveEdit === true\n","import {\n assertNotVariantVersion,\n disabledForVariantVersion,\n type VariantVersionDisabledReason,\n} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {operationsApiClient} from '../utils/operationsApiClient'\nimport {type OperationImpl} from './types'\n\nexport const del: OperationImpl<[], 'NOTHING_TO_DELETE' | VariantVersionDisabledReason> = {\n disabled: ({snapshots}) => {\n // Legacy transaction delete. Variant-scoped versions are disabled here — use\n // `serverOperations/delete.ts` instead.\n const variantDisabled = disabledForVariantVersion(snapshots?.version)\n if (variantDisabled) {\n return variantDisabled\n }\n return snapshots.draft || snapshots.published ? false : 'NOTHING_TO_DELETE'\n },\n execute: ({client, schema, idPair, typeName, snapshots}) => {\n assertNotVariantVersion(snapshots.version, 'delete')\n const tx = operationsApiClient(client, idPair)\n .observable.transaction()\n .delete(idPair.publishedId)\n\n if (isLiveEditEnabled(schema, typeName)) {\n return tx.commit({tag: 'document.delete'})\n }\n\n return tx.delete(idPair.draftId).commit({\n tag: 'document.delete',\n // this disables referential integrity for cross-dataset references. we\n // have this set because we warn against deletes in the `ConfirmDeleteDialog`\n // UI. This operation is run when \"delete anyway\" is clicked\n skipCrossDatasetReferenceValidation: true,\n })\n },\n}\n","import {\n assertNotVariantVersion,\n disabledForVariantVersion,\n type VariantVersionDisabledReason,\n} from '../utils/assertNotVariantVersion'\nimport {operationsApiClient} from '../utils/operationsApiClient'\nimport {type OperationImpl} from './types'\n\ntype DisabledReason = 'NO_CHANGES' | 'NOT_PUBLISHED' | VariantVersionDisabledReason\n\nexport const discardChanges: OperationImpl<[], DisabledReason> = {\n disabled: ({snapshots}) => {\n // Legacy transaction discard-changes. Variant-scoped versions are disabled here — use\n // `serverOperations/discardChanges.ts` instead.\n const variantDisabled = disabledForVariantVersion(snapshots?.version)\n if (variantDisabled) {\n return variantDisabled\n }\n if (!snapshots.draft) {\n return 'NO_CHANGES'\n }\n if (!snapshots.published) {\n return 'NOT_PUBLISHED'\n }\n return false\n },\n execute: ({client, idPair, snapshots}) => {\n assertNotVariantVersion(snapshots.version, 'discardChanges')\n return operationsApiClient(client, idPair)\n .observable.transaction()\n .delete(idPair.draftId)\n .commit({tag: 'document.discard-changes'})\n },\n}\n","import {type SanityDocument} from '@sanity/types'\n\nimport {getVariantId} from '../tool/util'\n\n/**\n * The routing information of a variant-scoped version document, derived from its `_system`.\n *\n */\nexport interface VariantVersionInfo {\n /** The short variant name (the `_.variants.` prefix stripped from `_system.variant._ref`). */\n variantId: string\n /**\n * The bundle the variant document belongs to: `'drafts'`, a release id, or `'published'` for\n * the variant-of-published document (which carries no `_system.bundleId`).\n */\n bundleId: 'drafts' | 'published' | (string & {})\n}\n\n/**\n * Derives variant routing information from a version document snapshot's `_system`, or\n * `undefined` when the document is not variant-scoped.\n *\n * This is the single discriminator the document operations use to decide between the base and\n * variant action paths. The `_system` field is authoritative and always present on variant\n * documents — only pre-migration non-variant documents may lack it, and those can never be\n * variant-scoped.\n *\n */\nexport function getVariantVersionInfo(\n version: SanityDocument | null | undefined,\n): VariantVersionInfo | undefined {\n const variantRef = version?._system?.variant?._ref\n if (!variantRef) {\n return undefined\n }\n\n return {\n // Strip the `_.variants.` document path prefix to the short variant id. Kept local (instead\n // of `getVariantId` from `variants/tool/util`) to avoid pulling tool-level modules — and\n // their import cycles — into the document store's operations graph.\n variantId: getVariantId(variantRef),\n bundleId: version._system?.bundleId ?? 'published',\n }\n}\n","import {type SanityDocument, type SanityDocumentLike} from '@sanity/types'\nimport omit from 'lodash-es/omit.js'\n\nimport {getDraftId, getVersionFromId, getVersionId} from '../../../../util/draftUtils'\nimport {getVariantVersionInfo} from '../../../../variants/documents/getVariantVersionInfo'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {operationsApiClient} from '../utils/operationsApiClient'\nimport {variantsApiClient} from '../utils/variantsApiClient'\nimport {type MapDocument, type OperationImpl} from './types'\n\n// `_system` is authoritative, server-managed metadata (`group`/`scopeId`/`release`/`variant`\n// references of the SOURCE document): copying it onto the duplicate would attach the new\n// document to the source's group and scope.\nconst omitProps = ['_createdAt', '_updatedAt', '_system']\n\n// Variant create addresses the new document by `(publishedId, variantId, bundleId)`; the\n// server generates the opaque version id. `_rev` is the source revision and must not\n// travel with the payload.\nconst variantOmitProps = [...omitProps, '_id', '_rev']\n\nconst getDocumentToDuplicateId = ({\n versionSnapshot,\n dupeId,\n liveEdit,\n}: {\n versionSnapshot?: SanityDocument | null | undefined\n dupeId: string\n liveEdit: boolean\n}) => {\n // When duplicating a version document we need to create it with a version id.\n // We get the version from the snapshot id and create a new version id for the duplicate.\n // Variant-scoped versions take a different path (`variant.create`) and never reach here.\n if (versionSnapshot) {\n const versionId = getVersionFromId(versionSnapshot._id)\n if (versionId) return getVersionId(dupeId, versionId)\n }\n\n if (liveEdit) {\n return dupeId\n }\n\n return getDraftId(dupeId)\n}\n\nconst mapDocumentNoop: MapDocument = (document) => document\n\nexport const duplicate: OperationImpl<\n [\n baseDocumentId: string,\n options?: {\n mapDocument?: MapDocument\n },\n ],\n 'NOTHING_TO_DUPLICATE'\n> = {\n disabled: ({snapshots}) => {\n return snapshots.published || snapshots.draft || snapshots.version\n ? false\n : 'NOTHING_TO_DUPLICATE'\n },\n execute: (\n {schema, client, snapshots, typeName, idPair},\n dupeId,\n {mapDocument = mapDocumentNoop} = {},\n ) => {\n const source = snapshots.version || snapshots.draft || snapshots.published\n\n if (!source) {\n throw new Error('cannot execute on empty document')\n }\n\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion) {\n // Scope ids are opaque and server-generated: never fabricate\n // `versions.<sourceScope>.<dupeId>`. Address the new document by coordinates\n // and let the action attach variant membership.\n const bundleId = variantVersion.bundleId === 'published' ? undefined : variantVersion.bundleId\n const mapped = mapDocument({\n ...source,\n _id: dupeId,\n _type: source._type,\n })\n\n return variantsApiClient(client).observable.action(\n {\n actionType: 'sanity.action.document.variant.create',\n publishedId: dupeId,\n variantId: variantVersion.variantId,\n ...(bundleId ? {bundleId} : {}),\n document: omit(mapped, variantOmitProps) as SanityDocumentLike,\n },\n {tag: 'document.duplicate'},\n )\n }\n\n const _id = getDocumentToDuplicateId({\n versionSnapshot: snapshots.version,\n dupeId,\n liveEdit: isLiveEditEnabled(schema, typeName),\n })\n\n return operationsApiClient(client, idPair).observable.create(\n omit(\n mapDocument({\n ...source,\n _id,\n _type: source._type,\n }),\n omitProps,\n // Performing `Omit` on a type that has an index signature causes the known properties to\n // be lost.\n ) as SanityDocumentLike,\n {\n tag: 'document.duplicate',\n },\n )\n },\n}\n","import {\n assertNotVariantVersion,\n disabledForVariantVersion,\n type VariantVersionDisabledReason,\n} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {type OperationImpl} from './types'\n\n// todo: we could also consider exposing 'mutate' directly\nexport const patch: OperationImpl<\n [patches: any[], initialDocument?: Record<string, any>],\n VariantVersionDisabledReason\n> = {\n // Legacy local patch. Variant-scoped versions are disabled here — use `serverOperations/patch.ts`\n // instead.\n disabled: ({snapshots}) => disabledForVariantVersion(snapshots?.version),\n execute: (\n {schema, snapshots, idPair, draft, published, version, typeName},\n patches = [],\n initialDocument,\n ): void => {\n assertNotVariantVersion(snapshots.version, 'patch')\n if (version) {\n // No drafting, so patch and commit the version document.\n version.mutate([\n version.createIfNotExists({\n _type: typeName,\n ...initialDocument,\n }),\n ...version.patch(patches),\n ])\n return\n }\n\n if (isLiveEditEnabled(schema, typeName)) {\n // No drafting, so patch and commit the published document\n published.mutate([\n published.createIfNotExists({\n _type: typeName,\n ...initialDocument,\n }),\n ...published.patch(patches),\n ])\n } else {\n draft.mutate([\n draft.createIfNotExists({\n ...initialDocument,\n ...snapshots.published,\n _id: idPair.draftId,\n _type: typeName,\n }),\n ...draft.patch(patches),\n ])\n }\n },\n}\n","import {isReference, type SanityDocument} from '@sanity/types'\nimport omit from 'lodash-es/omit.js'\n\nimport {\n assertNotVariantVersion,\n disabledForVariantVersion,\n type VariantVersionDisabledReason,\n} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {operationsApiClient} from '../utils/operationsApiClient'\nimport {type OperationImpl, type PublishOptions} from './types'\n\nfunction strengthenOnPublish<T>(obj: T): T {\n if (isReference(obj)) {\n if (obj._strengthenOnPublish) {\n return omit(\n obj,\n ['_strengthenOnPublish'].concat(obj._strengthenOnPublish.weak ? [] : ['_weak']),\n ) as T\n }\n return obj\n }\n if (typeof obj !== 'object' || !obj) return obj\n if (Array.isArray(obj)) return obj.map(strengthenOnPublish) as T\n return Object.fromEntries(\n Object.entries(obj).map(([key, value]) => [key, strengthenOnPublish(value)] as const),\n ) as T\n}\n\ntype DisabledReason =\n | 'LIVE_EDIT_ENABLED'\n | 'ALREADY_PUBLISHED'\n | 'NO_CHANGES'\n | VariantVersionDisabledReason\n\nexport const publish: OperationImpl<[options?: PublishOptions], DisabledReason> = {\n disabled: ({schema, typeName, snapshots}) => {\n // Legacy transaction publish. Variant-scoped versions are disabled here — use\n // `serverOperations/publish.ts` instead.\n const variantDisabled = disabledForVariantVersion(snapshots?.version)\n if (variantDisabled) {\n return variantDisabled\n }\n if (isLiveEditEnabled(schema, typeName)) {\n return 'LIVE_EDIT_ENABLED'\n }\n if (!snapshots.draft && !snapshots.version) {\n return snapshots.published ? 'ALREADY_PUBLISHED' : 'NO_CHANGES'\n }\n return false\n },\n execute: ({client, idPair, snapshots}) => {\n if (!snapshots.draft && !snapshots.version) {\n throw new Error('cannot execute \"publish\" when draft or version is missing')\n }\n assertNotVariantVersion(snapshots.version, 'publish')\n\n const value = strengthenOnPublish(\n omit(snapshots.draft || snapshots.version, '_updatedAt') as SanityDocument,\n )\n const tx = operationsApiClient(client, idPair).observable.transaction()\n\n if (snapshots.published) {\n // If it exists already, we only want to update it if the revision on the remote server\n // matches what our local state thinks it's at\n tx.patch(idPair.publishedId, {\n // Hack until other mutations support revision locking\n unset: ['_revision_lock_pseudo_field_'],\n ifRevisionID: snapshots.published._rev,\n })\n\n tx.createOrReplace({\n ...value,\n _id: idPair.publishedId,\n })\n } else {\n // If the document has not been published, we want to create it - if it suddenly exists\n // before being created, we don't want to overwrite if, instead we want to yield an error\n tx.create({\n ...value,\n _id: idPair.publishedId,\n })\n }\n\n tx.delete(value._id)\n\n return tx.commit({tag: 'document.publish', visibility: 'async'})\n },\n}\n","import {type DocumentRevision} from '../../../history/createHistoryStore'\nimport {assertNotVariantVersion, disabledForVariantVersion} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {type OperationImpl} from './types'\n\nexport const restore: OperationImpl<[fromRevision: DocumentRevision]> = {\n // Legacy restore. Variant-scoped versions are disabled here — use `serverOperations/restore.ts`\n // instead.\n disabled: ({snapshots}) => disabledForVariantVersion(snapshots?.version),\n execute: (\n {historyStore, schema, idPair, typeName, snapshots},\n fromRevision: DocumentRevision,\n ) => {\n assertNotVariantVersion(snapshots.version, 'restore')\n const targetId = idPair.versionId\n ? idPair.versionId\n : isLiveEditEnabled(schema, typeName)\n ? idPair.publishedId\n : idPair.draftId\n\n return historyStore.restore(idPair.publishedId, targetId, fromRevision)\n },\n}\n","import omit from 'lodash-es/omit.js'\n\nimport {\n assertNotVariantVersion,\n disabledForVariantVersion,\n type VariantVersionDisabledReason,\n} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {operationsApiClient} from '../utils/operationsApiClient'\nimport {type OperationImpl} from './types'\n\ntype DisabledReason = 'LIVE_EDIT_ENABLED' | 'NOT_PUBLISHED' | VariantVersionDisabledReason\n\nexport const unpublish: OperationImpl<[], DisabledReason> = {\n disabled: ({schema, snapshots, typeName}) => {\n // Legacy transaction unpublish. Variant-scoped versions are disabled here — use\n // `serverOperations/unpublish.ts` instead.\n const variantDisabled = disabledForVariantVersion(snapshots?.version)\n if (variantDisabled) {\n return variantDisabled\n }\n if (isLiveEditEnabled(schema, typeName)) {\n return 'LIVE_EDIT_ENABLED'\n }\n return snapshots.published ? false : 'NOT_PUBLISHED'\n },\n execute: ({client, idPair, snapshots}) => {\n assertNotVariantVersion(snapshots.version, 'unpublish')\n\n let tx = operationsApiClient(client, idPair).observable.transaction().delete(idPair.publishedId)\n\n if (snapshots.published) {\n tx = tx.createIfNotExists({\n ...omit(snapshots.published, '_updatedAt'),\n _id: idPair.draftId,\n _type: snapshots.published._type,\n })\n }\n\n return tx.commit({\n tag: 'document.unpublish',\n visibility: 'async',\n // this disables referential integrity for cross-dataset references. we\n // have this set because we warn against unpublishes in the `ConfirmDeleteDialog`\n // UI. This operation is run when \"unpublish anyway\" is clicked\n skipCrossDatasetReferenceValidation: true,\n })\n },\n}\n","import {isPublishedId} from '@sanity/client/csm'\n\nimport {type OperationImpl} from '../operations/types'\nimport {actionsApiClient} from '../utils/actionsApiClient'\n\nexport const del: OperationImpl<[versions?: string[]], 'NOTHING_TO_DELETE'> = {\n disabled: ({snapshots}) =>\n snapshots.draft || snapshots.published || snapshots.version ? false : 'NOTHING_TO_DELETE',\n execute: ({client, idPair, snapshots}, versions = []) => {\n //the delete action requires a published doc -- discard versions if not present\n if (!snapshots.published) {\n return actionsApiClient(client, idPair).observable.action(\n versions.map((versionId) => ({\n actionType: 'sanity.action.document.version.discard',\n versionId,\n })),\n {\n skipCrossDatasetReferenceValidation: true,\n },\n )\n }\n\n return actionsApiClient(client, idPair).observable.action(\n {\n actionType: 'sanity.action.document.delete',\n includeDrafts: versions\n ? // if versions are provided, remove the published id from the list, all versions need to be included in order for the delete to work.\n versions.filter((v) => !isPublishedId(v))\n : snapshots.draft\n ? [idPair.draftId]\n : [],\n publishedId: idPair.publishedId,\n },\n {\n tag: 'document.delete',\n // this disables referential integrity for cross-dataset references. we\n // have this set because we warn against deletes in the `ConfirmDeleteDialog`\n // UI. This operation is run when \"delete anyway\" is clicked\n skipCrossDatasetReferenceValidation: true,\n },\n )\n },\n}\n","import {getVariantVersionInfo} from '../../../../variants/documents/getVariantVersionInfo'\nimport {type OperationImpl} from '../operations/types'\nimport {actionsApiClient} from '../utils/actionsApiClient'\n\ntype DisabledReason = 'NO_CHANGES'\n\nexport const discardChanges: OperationImpl<[], DisabledReason> = {\n disabled: ({snapshots}) => {\n if (!snapshots.draft && !snapshots.version) {\n return 'NO_CHANGES'\n }\n // The variant-of-published document has no draft-ness to discard; removing the published\n // variant is unpublish's job.\n if (getVariantVersionInfo(snapshots.version)?.bundleId === 'published') {\n return 'NO_CHANGES'\n }\n return false\n },\n execute: ({client, idPair, snapshots}) => {\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion?.bundleId === 'published') {\n throw new Error('Cannot discard changes of a published variant: unpublish it instead')\n }\n\n return actionsApiClient(client, idPair).observable.action(\n {\n actionType: 'sanity.action.document.version.discard',\n versionId: idPair.versionId || idPair.draftId,\n },\n {tag: 'document.discard-changes'},\n )\n },\n}\n","import {type OperationImpl} from '../operations/types'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\n\nexport const patch: OperationImpl<[patches: any[], initialDocument?: Record<string, any>]> = {\n disabled: (): false => false,\n execute: (\n {schema, snapshots, idPair, draft, published, version, typeName},\n patches = [],\n initialDocument,\n ): void => {\n if (version) {\n // No drafting, so patch and commit the version document.\n const patchMutation = version.patch(patches)\n // Note: if the document doesn't exist on the server yet, we need to create it first. We only want to do this if we can't see it locally\n // if it's been deleted on the server we want that to become a mutation error when submitting.\n const ensureVersion = snapshots.version\n ? version.patch([\n {\n unset: ['_empty_action_guard_pseudo_field_'],\n },\n ])\n : [\n version.create({\n ...initialDocument,\n _id: idPair.draftId,\n _type: typeName,\n }),\n ]\n // No drafting, so patch and commit the published document\n version.mutate([...ensureVersion, ...patchMutation])\n\n return\n }\n\n if (isLiveEditEnabled(schema, typeName)) {\n // No drafting, so patch and commit the published document\n const patchMutation = published.patch(patches)\n // Note: if the document doesn't exist on the server yet, we need to create it first. We only want to do this if we can't see it locally\n // if it's been deleted on the server we want that to become a mutation error when submitting.\n const mutations = snapshots.published\n ? patchMutation\n : [\n published.createIfNotExists({\n _type: typeName,\n ...initialDocument,\n }),\n ...patchMutation,\n ]\n // No drafting, so patch and commit the published document\n published.mutate(mutations)\n\n return\n }\n\n const patchMutation = draft.patch(patches)\n if (snapshots.draft) {\n draft.mutate([\n ...draft.patch([{unset: ['_empty_action_guard_pseudo_field_']}]),\n ...patchMutation,\n ])\n return\n }\n\n // At this point we don't have a draft, so we need to create it.\n // Only use the createMutation if the draft doesn't exist.\n // Creation will happen in a different transaction than the patch, to get the correct initial value for it.\n\n const createMutation = snapshots.published\n ? // If there's no draft, the user's edits will be based on the published document in the form in front of them\n // so before patching it we need to make sure it's created based on the current published version first.\n draft.createIfNotExists({\n ...initialDocument,\n ...snapshots.published,\n _id: idPair.draftId,\n _type: typeName,\n })\n : // If the published doesn't exist we need to trigger a `create` action, because we are internally\n // transforming the createIfNotExists action to a patch, which requires the published document to exist.\n // see checkoutPair.ts toActions function for more details.\n draft.create({\n ...initialDocument,\n _id: idPair.draftId,\n _type: typeName,\n })\n\n draft.mutate([createMutation])\n // Commit so we create the draft in a different transaction than the patch, and we get the correct initial value for it.\n draft.commit()\n // We do it in two steps to first create the draft with the copied version and then reflect the user edit to preserve the history.\n draft.mutate(patchMutation)\n },\n}\n","import {getVariantVersionInfo} from '../../../../variants/documents/getVariantVersionInfo'\nimport {type OperationImpl, type PublishOptions} from '../operations/types'\nimport {actionsApiClient} from '../utils/actionsApiClient'\nimport {assertNotVariantVersion} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {variantsApiClient} from '../utils/variantsApiClient'\n\ntype DisabledReason = 'LIVE_EDIT_ENABLED' | 'ALREADY_PUBLISHED' | 'NO_CHANGES' | 'NOT_PUBLISHABLE'\n\nexport const publish: OperationImpl<[options?: PublishOptions], DisabledReason> = {\n disabled: ({schema, typeName, snapshots}) => {\n if (isLiveEditEnabled(schema, typeName)) {\n return 'LIVE_EDIT_ENABLED'\n }\n\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion) {\n // The checked-out version IS the variant-of-published document: nothing to publish.\n if (variantVersion.bundleId === 'published') {\n return 'ALREADY_PUBLISHED'\n }\n // Release-scoped variant documents are published as part of their release, mirroring how\n // plain release versions are not publishable by this action.\n if (snapshots.version?._system?.release?._ref) {\n return 'NOT_PUBLISHABLE'\n }\n return false\n }\n\n if (!snapshots.draft && !snapshots.version) {\n return snapshots.published ? 'ALREADY_PUBLISHED' : 'NO_CHANGES'\n }\n return false\n },\n execute: ({client, idPair, snapshots}, options) => {\n // The editor must be able to see the draft they are choosing to publish.\n if (!snapshots.draft && !snapshots.version) {\n throw new Error('cannot execute \"publish\" when draft or version is missing')\n }\n if (idPair.versionId && !snapshots.version) {\n throw new Error('cannot execute \"publish\" when version is missing but versionId is provided')\n }\n\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion) {\n if (variantVersion.bundleId === 'published') {\n throw new Error(\n 'cannot execute \"publish\" on a variant-of-published document: it is already published',\n )\n }\n\n // Publishes the variant document into the variant-of-published document. The base\n // published document is never touched.\n //\n // `publishedRevisionId` → `ifPublishedVariantRevisionId` locks on the\n // variant-of-published sibling revision (passed from PublishAction via\n // `publishedSibling._rev` — that sibling is not in any pair snapshot slot).\n // `ifSourceRevisionId` is still omitted: the deployed action rejects it\n // (`json: unknown field`).\n // TODO(SAPP): send `ifSourceRevisionId: snapshots.version?._rev` once the action supports it.\n return variantsApiClient(client).observable.action(\n {\n actionType: 'sanity.action.document.variant.publish',\n publishedId: idPair.publishedId,\n variantId: variantVersion.variantId,\n bundleId: variantVersion.bundleId,\n ifPublishedVariantRevisionId: options?.publishedRevisionId,\n },\n {tag: 'document.publish'},\n )\n }\n\n assertNotVariantVersion(snapshots.version, 'publish')\n\n return actionsApiClient(client, idPair).observable.action(\n {\n actionType: 'sanity.action.document.publish',\n draftId: (snapshots.version?._id || snapshots.draft?._id)!,\n publishedId: idPair.publishedId,\n // Optimistic locking using `ifPublishedRevisionId` ensures that concurrent publish action\n // invocations do not override each other. Prefer an explicit `publishedRevisionId` when\n // provided; otherwise fall back to the published snapshot (the normal draft path).\n //\n // Note: for custom publish actions, `snapshots.draft._rev` may be stale, which means the\n // `ifDraftRevisionId` optimistic lock cannot currently be used.\n ifPublishedRevisionId: options?.publishedRevisionId ?? snapshots.published?._rev,\n },\n {\n tag: 'document.publish',\n },\n )\n },\n}\n","import {type DocumentRevision} from '../../../history/createHistoryStore'\nimport {type OperationImpl} from '../operations/types'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\n\nexport const restore: OperationImpl<[fromRevision: DocumentRevision]> = {\n disabled: (): false => false,\n execute: (\n {snapshots, historyStore, schema, idPair, typeName},\n fromRevision: DocumentRevision,\n ) => {\n const targetId = idPair.versionId\n ? idPair.versionId\n : isLiveEditEnabled(schema, typeName)\n ? idPair.publishedId\n : idPair.draftId\n\n return historyStore.restore(idPair.publishedId, targetId, fromRevision, {\n fromDeleted: !snapshots.draft && !snapshots.published,\n useServerDocumentActions: true,\n })\n },\n}\n","import {type SanityDocument} from '@sanity/client'\nimport {type SanityDocumentLike} from '@sanity/types'\n\n/**\n * checks if the document has been set for unpublishing\n * @internal\n *\n * @param document - sanity document\n * @returns boolean if the system delete is set\n */\nexport function isGoingToUnpublish(document: SanityDocument | SanityDocumentLike): boolean {\n return Boolean(document._system?.delete === true)\n}\n","import {isGoingToUnpublish} from '../../../../releases/util/isGoingToUnpublish'\nimport {getVariantVersionInfo} from '../../../../variants/documents/getVariantVersionInfo'\nimport {VARIANTS_STUDIO_CLIENT_OPTIONS} from '../../../../variants/store/constants'\nimport {type OperationImpl} from '../operations/types'\nimport {actionsApiClient} from '../utils/actionsApiClient'\nimport {assertNotVariantVersion} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {variantsApiClient} from '../utils/variantsApiClient'\n\ntype DisabledReason = 'LIVE_EDIT_ENABLED' | 'NOT_PUBLISHED' | 'ALREADY_UNPUBLISHED'\n\nexport const unpublish: OperationImpl<[], DisabledReason> = {\n disabled: ({schema, snapshots, typeName, idPair}) => {\n if (isLiveEditEnabled(schema, typeName) && !idPair.versionId) {\n return 'LIVE_EDIT_ENABLED'\n }\n\n // A release version already carrying the unpublish marker would be a no-op: the release\n // publish will remove the published document either way. Reverting it is a separate\n // operation (`revertUnpublishVersion`), not a repeated unpublish.\n if (idPair.versionId && snapshots.version && isGoingToUnpublish(snapshots.version)) {\n return 'ALREADY_UNPUBLISHED'\n }\n\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion) {\n // Unpublishable variant versions:\n // - the variant-of-published document itself (no bundleId), which is hard-unpublished\n // - a release-scoped variant, which is soft-unpublished as part of its release\n // A drafts-scoped variant has nothing published in its slot to unpublish.\n return variantVersion.bundleId !== 'drafts' ? false : 'NOT_PUBLISHED'\n }\n\n return snapshots.published ? false : 'NOT_PUBLISHED'\n },\n execute: ({client, idPair, snapshots}) => {\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion) {\n if (variantVersion.bundleId === 'drafts') {\n throw new Error('Cannot unpublish a draft variant')\n }\n // `bundleId` is the version snapshot's own bundle:\n // - `undefined` (variant-of-published): hard unpublish — the backend deletes the published\n // variant and creates the variant draft from its content (mirror of base unpublish)\n // - a release id: soft unpublish — the backend marks the release-scoped variant with\n // `_system.delete: true`, completed when the release is published\n // The base published and draft documents are never touched either way.\n return variantsApiClient(client).observable.action(\n {\n actionType: 'sanity.action.document.variant.unpublish',\n publishedId: idPair.publishedId,\n variantId: variantVersion.variantId,\n bundleId: snapshots.version?._system?.bundleId,\n },\n {\n tag: 'document.unpublish',\n skipCrossDatasetReferenceValidation: true,\n },\n )\n }\n\n assertNotVariantVersion(snapshots.version, 'unpublish')\n\n if (idPair.versionId) {\n // Unpublishing inside a release is a soft unpublish: the backend marks the release version\n // with `_system.delete: true` and removes the published document when the release is\n // published. The base draft is deliberately absent from the payload — unlike the base\n // unpublish below, nothing is written back into `drafts.<id>`.\n return actionsApiClient(client, idPair).observable.action(\n {\n actionType: 'sanity.action.document.version.unpublish',\n versionId: idPair.versionId,\n publishedId: idPair.publishedId,\n },\n {\n tag: 'document.unpublish',\n skipCrossDatasetReferenceValidation: true,\n },\n )\n }\n\n return actionsApiClient(client, idPair).observable.action(\n {\n // This operation is run when \"unpublish anyway\" is clicked\n actionType: 'sanity.action.document.unpublish',\n draftId: idPair.draftId,\n publishedId: idPair.publishedId,\n },\n {\n tag: 'document.unpublish',\n // this disables referential integrity for cross-dataset references. we\n // have this set because we warn against unpublishes in the `ConfirmDeleteDialog`\n // UI.\n skipCrossDatasetReferenceValidation: true,\n },\n )\n },\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type Schema} from '@sanity/types'\nimport {asyncScheduler, defer, EMPTY, merge, type Observable, of, Subject, timer} from 'rxjs'\nimport {\n catchError,\n concatMap,\n filter,\n groupBy,\n last,\n map,\n mergeMap,\n mergeMapTo,\n share,\n switchMap,\n take,\n tap,\n throttleTime,\n} from 'rxjs/operators'\n\nimport {type HistoryStore} from '../../history/createHistoryStore'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {createMemoKey, getClientCredentialSegments} from '../utils/memoKey'\nimport {consistencyStatus} from './consistencyStatus'\nimport {getOperationStoreKey} from './getOperationStoreKey'\nimport {operationArgs} from './operationArgs'\nimport {commit} from './operations/commit'\nimport {del} from './operations/delete'\nimport {discardChanges} from './operations/discardChanges'\nimport {duplicate} from './operations/duplicate'\nimport {patch} from './operations/patch'\nimport {publish} from './operations/publish'\nimport {restore} from './operations/restore'\nimport {type OperationArgs, type OperationsAPI} from './operations/types'\nimport {unpublish} from './operations/unpublish'\nimport {del as serverDel} from './serverOperations/delete'\nimport {discardChanges as serverDiscardChanges} from './serverOperations/discardChanges'\nimport {patch as serverPatch} from './serverOperations/patch'\nimport {publish as serverPublish} from './serverOperations/publish'\nimport {restore as serverRestore} from './serverOperations/restore'\nimport {unpublish as serverUnpublish} from './serverOperations/unpublish'\n\ninterface ExecuteArgs {\n operationName: keyof OperationsAPI\n idPair: IdPair\n typeName: string\n storeKey?: string\n extraArgs: any[]\n}\n\nfunction maybeObservable(v: void | Observable<any>) {\n return typeof v === 'undefined' ? of(null) : v\n}\n\nconst operationImpls = {\n del: del,\n delete: del,\n publish,\n patch,\n commit,\n discardChanges,\n unpublish,\n duplicate,\n restore,\n} as const\n\n//as we add server operations one by one, we can add them here\n// Note: Any changes must also be made to `createOperationsAPI`, which is defined in `packages/sanity/src/core/store/document/document-pair/operations/helpers.ts`.\nconst serverOperationImpls = {\n ...operationImpls,\n del: serverDel,\n delete: serverDel,\n discardChanges: serverDiscardChanges,\n patch: serverPatch,\n publish: serverPublish,\n unpublish: serverUnpublish,\n restore: serverRestore,\n}\n\nconst execute = (\n operationName: keyof typeof operationImpls,\n operationArguments: OperationArgs,\n extraArgs: any[],\n): Observable<any> => {\n const operation = serverOperationImpls[operationName]\n return defer(() =>\n merge(of(null), maybeObservable(operation.execute(operationArguments, ...extraArgs))),\n ).pipe(last())\n}\n\nconst operationCalls$ = new Subject<ExecuteArgs>()\n\n/** @internal */\nexport function emitOperation(\n operationName: keyof OperationsAPI,\n idPair: IdPair,\n typeName: string,\n extraArgs: any[],\n storeKey?: string,\n): void {\n operationCalls$.next({operationName, idPair, typeName, storeKey, extraArgs})\n}\n\n// These are the operations that cannot be performed while the document is in an inconsistent state\nconst REQUIRES_CONSISTENCY = ['publish', 'unpublish', 'discardChanges', 'delete']\n\n/**\n * @hidden\n * @beta */\nexport interface OperationError {\n type: 'error'\n /** @internal */\n op: keyof OperationsAPI\n id: string\n error: Error\n idPair: IdPair\n}\n\n/**\n * @hidden\n * @beta */\nexport interface OperationSuccess {\n type: 'success'\n /** @internal */\n op: keyof OperationsAPI\n id: string\n idPair: IdPair\n}\n\ninterface IntermediarySuccess {\n type: 'success'\n args: ExecuteArgs\n}\n\ninterface IntermediaryError {\n type: 'error'\n args: ExecuteArgs\n error: any\n}\n\n/** @internal */\nexport const operationEvents = memoize(\n (ctx: {\n client: SanityClient\n historyStore: HistoryStore\n schema: Schema\n /**\n * @deprecated Does nothing. Preserved to avoid breaking changes.\n * Will be removed in the next major version.\n */\n serverActionsEnabled?: Observable<boolean>\n extraOptions?: DocumentStoreExtraOptions\n }) => {\n const storeKey = getOperationStoreKey(ctx.client)\n const result$: Observable<IntermediarySuccess | IntermediaryError> = operationCalls$.pipe(\n filter((op) => op.storeKey === storeKey || !op.storeKey),\n groupBy((op) => op.idPair.publishedId),\n mergeMap((groups$) =>\n groups$.pipe(\n // although it might look like a bug, dropping pending async operations here is actually a feature\n // E.g. if the user types `publish` which is async and then starts patching (sync) then the publish\n // should be cancelled\n switchMap((args) =>\n operationArgs(ctx, args.idPair, args.typeName).pipe(\n take(1),\n switchMap((operationArguments) => {\n const requiresConsistency = REQUIRES_CONSISTENCY.includes(args.operationName)\n if (requiresConsistency) {\n operationArguments.published.commit()\n operationArguments.draft.commit()\n operationArguments.version?.commit()\n }\n const isConsistent$ = consistencyStatus(\n ctx.client,\n args.idPair,\n args.typeName,\n ctx.extraOptions,\n ).pipe(filter(Boolean))\n const ready$ = requiresConsistency ? isConsistent$.pipe(take(1)) : of(true)\n return ready$.pipe(\n switchMap(() => execute(args.operationName, operationArguments, args.extraArgs)),\n )\n }),\n map((): IntermediarySuccess => ({type: 'success', args})),\n catchError((err): Observable<IntermediaryError> =>\n of({type: 'error', args, error: err}),\n ),\n ),\n ),\n ),\n ),\n share(),\n )\n\n // this enables autocommit after patch operations\n const AUTOCOMMIT_INTERVAL = 1000\n const autoCommit$ = result$.pipe(\n filter((result) => result.type === 'success' && result.args.operationName === 'patch'),\n throttleTime(AUTOCOMMIT_INTERVAL, asyncScheduler, {leading: true, trailing: true}),\n concatMap((result) =>\n (window as any).SLOW ? timer(10000).pipe(map(() => result)) : of(result),\n ),\n tap((result) => {\n emitOperation('commit', result.args.idPair, result.args.typeName, [], result.args.storeKey)\n }),\n )\n\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n return merge(result$, autoCommit$.pipe(mergeMapTo(EMPTY)))\n },\n (ctx) =>\n // Per credential (token+dataset+projectId): this captures `ctx.client` and\n // drives commits/mutations through it, so a cross-tab re-login (new token)\n // must get a fresh entry rather than replaying the stale-token client. See\n // getClientCredentialSegments.\n createMemoKey(getClientCredentialSegments(ctx.client)),\n)\n","import {type IdPair} from '../../types'\nimport {getOperationStoreKey} from '../getOperationStoreKey'\nimport {emitOperation} from '../operationEvents'\nimport {del as serverDel} from '../serverOperations/delete'\nimport {discardChanges as serverDiscardChanges} from '../serverOperations/discardChanges'\nimport {patch as serverPatch} from '../serverOperations/patch'\nimport {publish as serverPublish} from '../serverOperations/publish'\nimport {restore as serverRestore} from '../serverOperations/restore'\nimport {unpublish as serverUnpublish} from '../serverOperations/unpublish'\nimport {commit} from './commit'\nimport {duplicate} from './duplicate'\nimport {type Operation, type OperationArgs, type OperationImpl, type OperationsAPI} from './types'\n\nfunction createOperationGuard(opName: string): Operation<any[], 'NOT_READY'> {\n return {\n disabled: 'NOT_READY',\n execute: () => {\n throw new Error(`Called ${opName} before it was ready.`)\n },\n }\n}\n\n// This creates a version of the operations api that will throw if called.\n// Most operations depend on having the \"current document state\" available locally and if an action gets called\n// before we have the state available, we throw an error to signal \"premature\" invocation before ready\nexport const GUARDED: OperationsAPI = {\n commit: createOperationGuard('commit'),\n delete: createOperationGuard('delete'),\n del: createOperationGuard('del'),\n publish: createOperationGuard('publish'),\n patch: createOperationGuard('patch'),\n discardChanges: createOperationGuard('discardChanges'),\n unpublish: createOperationGuard('unpublish'),\n duplicate: createOperationGuard('duplicate'),\n restore: createOperationGuard('restore'),\n}\n\nfunction createTargetNotFoundOperation(opName: string): Operation<any[], 'TARGET_NOT_FOUND'> {\n return {\n disabled: 'TARGET_NOT_FOUND',\n execute: () => {\n throw new Error(\n `Cannot execute \"${opName}\": the selected target (release or variant) does not contain this document.`,\n )\n },\n }\n}\n\n// The operations api emitted when the declared target (release or variant) has no document.\n// Every operation is disabled and throws if executed anyway: falling back to the base\n// draft/published pair in this state is exactly the failure mode the guard exists to prevent.\nexport const TARGET_NOT_FOUND_OPERATIONS: OperationsAPI = {\n commit: createTargetNotFoundOperation('commit'),\n delete: createTargetNotFoundOperation('delete'),\n del: createTargetNotFoundOperation('del'),\n publish: createTargetNotFoundOperation('publish'),\n patch: createTargetNotFoundOperation('patch'),\n discardChanges: createTargetNotFoundOperation('discardChanges'),\n unpublish: createTargetNotFoundOperation('unpublish'),\n duplicate: createTargetNotFoundOperation('duplicate'),\n restore: createTargetNotFoundOperation('restore'),\n}\nconst OPERATION_NAMES = Object.keys(GUARDED) as (keyof OperationsAPI)[]\n\n/**\n * `execute` only emits the operation name with the id pair, type name and store key the api\n * was created for; the arguments are read from the live `operationArgs` stream at execution\n * time. `disabled` is therefore the only field a consumer can observe changing.\n */\nexport function hasSameDisabledState(a: OperationsAPI, b: OperationsAPI): boolean {\n return OPERATION_NAMES.every((name) => a[name].disabled === b[name].disabled)\n}\n\nconst createEmitter =\n (operationName: keyof OperationsAPI, idPair: IdPair, typeName: string, storeKey: string) =>\n (...executeArgs: any[]) =>\n emitOperation(operationName, idPair, typeName, executeArgs, storeKey)\n\nfunction wrap<ExtraArgs extends any[], DisabledReason extends string>(\n opName: keyof OperationsAPI,\n op: OperationImpl<ExtraArgs, DisabledReason>,\n operationArgs: OperationArgs,\n): Operation<ExtraArgs, DisabledReason> {\n const disabled = op.disabled(operationArgs)\n const storeKey = getOperationStoreKey(operationArgs.client)\n return {\n disabled,\n execute: createEmitter(opName, operationArgs.idPair, operationArgs.typeName, storeKey),\n }\n}\n\nexport function createOperationsAPI(args: OperationArgs): OperationsAPI {\n const operations: OperationsAPI = {\n commit: wrap('commit', commit, args),\n duplicate: wrap('duplicate', duplicate, args),\n delete: wrap('delete', serverDel, args),\n del: wrap('delete', serverDel, args),\n discardChanges: wrap('discardChanges', serverDiscardChanges, args),\n patch: wrap('patch', serverPatch, args),\n publish: wrap('publish', serverPublish, args),\n unpublish: wrap('unpublish', serverUnpublish, args),\n restore: wrap('restore', serverRestore, args),\n }\n\n // Self-derived target guard: a version was requested for an existing document, but the version\n // document doesn't exist. Mutating in this state would silently manifest the version out of\n // thin air (`patch` creates the version document) or operate on the base pair (`publish` would\n // publish the draft), so the mutating operations are disabled regardless of what the caller\n // declared. Deliberately excluded:\n // - New documents (no draft, published, or version snapshots): typing must still create the\n // release version locally via its deterministic id (create-on-first-edit).\n // - `restore` (history restore into a release) legitimately creates missing versions.\n // - `delete` / `duplicate` operate on the whole document group.\n const targetVersionMissing = Boolean(\n args.idPair.versionId &&\n !args.snapshots.version &&\n (args.snapshots.draft || args.snapshots.published),\n )\n\n if (!targetVersionMissing) {\n return operations\n }\n\n // A declared creatable variant target: the variant document doesn't exist yet, but its id is\n // known ahead of time (the server-advertised `_system.draft` weak ref on the variant-of-published\n // sibling), so typing must create it seeded from the published variant — exactly like the base\n // pair creates the draft from published. Only `patch` and `commit` are exempted: the document\n // still doesn't exist, so publish/unpublish/discardChanges stay `TARGET_NOT_FOUND` until it does.\n const allowVersionCreate = args.target?.kind === 'variant' && args.target.allowCreate === true\n\n return {\n ...operations,\n commit: allowVersionCreate ? operations.commit : createTargetNotFoundOperation('commit'),\n patch: allowVersionCreate ? operations.patch : createTargetNotFoundOperation('patch'),\n publish: createTargetNotFoundOperation('publish'),\n unpublish: createTargetNotFoundOperation('unpublish'),\n discardChanges: createTargetNotFoundOperation('discardChanges'),\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type Schema} from '@sanity/types'\nimport {concat, EMPTY, merge, type Observable, of} from 'rxjs'\nimport {distinctUntilChanged, map, mergeMap, shareReplay} from 'rxjs/operators'\n\nimport {type HistoryStore} from '../../history/createHistoryStore'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type DocumentPairTarget, type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {memoizeKeyGen} from './memoizeKeyGen'\nimport {operationArgs} from './operationArgs'\nimport {operationEvents} from './operationEvents'\nimport {createOperationsAPI, GUARDED, hasSameDisabledState} from './operations/helpers'\nimport {type OperationsAPI} from './operations/types'\n\nexport const editOperations = memoize(\n (\n ctx: {\n client: SanityClient\n historyStore: HistoryStore\n schema: Schema\n pairListenerOptions?: DocumentStoreExtraOptions\n },\n idPair: IdPair,\n typeName: string,\n // The declared pair target. Threaded into `OperationArgs` (not into the shared, memoized\n // `operationArgs` stream) so the self-derived missing-version guard can honor a declared\n // creatable variant target (`allowCreate`).\n target?: DocumentPairTarget,\n ): Observable<OperationsAPI> => {\n const operationEvents$ = operationEvents(ctx)\n\n const operationArgs$ = operationArgs(ctx, idPair, typeName)\n const operations$ = operationArgs$.pipe(\n map((args) => createOperationsAPI({...args, target})),\n distinctUntilChanged(hasSameDisabledState),\n )\n\n // To makes sure we connect the stream that actually performs the operations\n return concat(\n of(GUARDED),\n merge(operationEvents$.pipe(mergeMap(() => EMPTY)), operations$),\n ).pipe(shareReplay({refCount: true, bufferSize: 1}))\n },\n (ctx, idPair, typeName, target) =>\n // `allowCreate` changes the emitted operations for the same pair, so it must partake in the\n // memo key or a creatable and a non-creatable caller would collide on one cached stream.\n `${memoizeKeyGen(ctx.client, idPair, typeName)}-${\n target?.kind === 'variant' && target.allowCreate ? 'allow-create' : ''\n }`,\n)\n","// api extractor take issues with 'as const' for literals\n// oxlint-disable-next-line prefer-as-const\nexport const RELEASE_DOCUMENT_TYPE: 'system.release' = 'system.release'\nexport const RELEASE_DOCUMENTS_PATH = '_.releases'\n","import {type ReleaseId} from '../../perspective/types'\nimport {RELEASE_DOCUMENTS_PATH} from '../store/constants'\n\nconst PATH_ID_PREFIX = `${RELEASE_DOCUMENTS_PATH}.`\n\n/**\n * Whether the given id addresses a release document (`_.releases.<releaseId>`) rather than\n * being a release id or a system bundle name.\n *\n * @internal\n */\nexport function isReleaseDocumentId(id: string): boolean {\n return id.startsWith(PATH_ID_PREFIX)\n}\n\n/**\n * @internal\n * @param releaseDocumentId - the document id of the release\n */\nexport function getReleaseIdFromReleaseDocumentId(releaseDocumentId: string): ReleaseId {\n if (!releaseDocumentId.startsWith(PATH_ID_PREFIX)) {\n throw new Error(\n `Release document ID was ${releaseDocumentId} but should start with ${RELEASE_DOCUMENTS_PATH}`,\n )\n }\n const releaseId = releaseDocumentId.slice(PATH_ID_PREFIX.length)\n return releaseId\n}\n","import {type MonoTypeOperatorFunction} from 'rxjs'\nimport {tap} from 'rxjs/operators'\n\n/**\n * RxJS operator that measures the time from subscription to the first emission.\n * Calls `onMeasured` once with the elapsed duration in milliseconds and the emitted value.\n * Uses `tap()` internally so data flow is unchanged.\n *\n * Re-subscriptions (e.g. navigating between documents) naturally produce fresh measurements.\n *\n * @param onMeasured - Callback receiving the duration in ms and the first emitted value\n * @returns An RxJS operator\n * @internal\n */\nexport function measureFirstEmission<T>(\n onMeasured: (durationMs: number, value: T) => void,\n): MonoTypeOperatorFunction<T> {\n return (source) => {\n let measured = false\n let startTime: number\n\n return source.pipe(\n tap({\n subscribe: () => {\n measured = false\n startTime = performance.now()\n },\n next: (value) => {\n if (!measured) {\n measured = true\n onMeasured(performance.now() - startTime, value)\n }\n },\n }),\n )\n }\n}\n\n/**\n * RxJS operator that measures the time from subscription to the first emission\n * where the given predicate returns `true`.\n * Calls `onMeasured` once with the elapsed duration in milliseconds and the matching value.\n * Uses `tap()` internally so data flow is unchanged.\n *\n * @param predicate - Function that determines if the emitted value is a match\n * @param onMeasured - Callback receiving the duration in ms and the first matching value\n * @returns An RxJS operator\n * @internal\n */\nexport function measureFirstMatch<T>(\n predicate: (value: T) => boolean,\n onMeasured: (durationMs: number, value: T) => void,\n): MonoTypeOperatorFunction<T> {\n return (source) => {\n let measured = false\n let startTime: number\n\n return source.pipe(\n tap({\n subscribe: () => {\n measured = false\n startTime = performance.now()\n },\n next: (value) => {\n if (!measured && predicate(value)) {\n measured = true\n onMeasured(performance.now() - startTime, value)\n }\n },\n }),\n )\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type SanityDocument, type Schema} from '@sanity/types'\nimport {combineLatest, type Observable, of, ReplaySubject, timer} from 'rxjs'\nimport {map, share, startWith, switchMap} from 'rxjs/operators'\n\nimport {getReleaseIdFromReleaseDocumentId} from '../../../releases/util/getReleaseIdFromReleaseDocumentId'\nimport {getVersionFromId} from '../../../util/draftUtils'\nimport {measureFirstEmission} from '../../../util/measureFirstEmission'\nimport {createSWR} from '../../../util/rxSwr'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair, type PendingMutationsEvent} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {memoizeKeyGen} from './memoizeKeyGen'\nimport {snapshotPair} from './snapshotPair'\nimport {isLiveEditEnabled} from './utils/isLiveEditEnabled'\n\ninterface TransactionSyncLockState {\n enabled: boolean\n}\n\nconst swr = createSWR<\n [SanityDocument, SanityDocument, TransactionSyncLockState, SanityDocument | null]\n>({maxSize: 50})\n\n/**\n * @hidden\n * @beta */\nexport interface EditStateFor {\n id: string\n type: string\n transactionSyncLock: TransactionSyncLockState | null\n draft: SanityDocument | null\n published: SanityDocument | null\n version: SanityDocument | null\n /**\n * Whether live edit is enabled. This may be true for various reasons:\n *\n * - The schema type has live edit enabled.\n * - A version of the document is checked out.\n */\n liveEdit: boolean\n /**\n * Whether the schema type has live edit enabled.\n */\n liveEditSchemaType: boolean\n ready: boolean\n /**\n * When editing a version, the short name of the release the document belongs to (or an agent /\n * anonymous bundle name), matched by consumers against active release names. Never an opaque\n * variant scope hash: documents carrying full `_system` metadata are classified from\n * `_system.release` (normalized from the `_.releases.<name>` reference), so drafts- and\n * published-scoped variants report `undefined` while release-scoped versions — variant or not —\n * report their release. Until the first snapshot arrives, the bundle segment is reported as-is.\n */\n release: string | undefined\n /**\n * When editing a version, the bundle segment of the version document id\n * (`versions.<scopeId>.<groupId>`): a release id, an agent/anonymous bundle name, or an opaque\n * variant scope hash. `undefined` when editing the base draft/published pair.\n */\n scopeId: string | undefined\n}\nconst LOCKED: TransactionSyncLockState = {enabled: true}\nconst NOT_LOCKED: TransactionSyncLockState = {enabled: false}\n\n/**\n * Classifies `EditStateFor.release` from a version snapshot.\n *\n * Documents carrying the full `_system` metadata (`_system.group` present) are classified from\n * `_system.release`, which is authoritative: a reference to the release document\n * (`_.releases.<name>`), normalized here to the short release name every consumer matches\n * against. Version documents without a release reference (e.g. drafts- or published-scoped\n * variants) report `undefined`.\n *\n * Unmigrated documents (no `_system.group`) can only be plain release versions, so the bundle\n * segment of their id (`scopeId`) is the release name.\n */\nfunction classifyRelease(\n versionSnapshot: SanityDocument | null,\n scopeId: string | undefined,\n): string | undefined {\n if (!versionSnapshot || !versionSnapshot._system?.group) {\n return scopeId\n }\n const releaseRef = versionSnapshot._system.release?._ref\n if (!releaseRef) {\n return undefined\n }\n return getReleaseIdFromReleaseDocumentId(releaseRef)\n}\n\n/**\n * The edit state before any snapshot has arrived. `editState` emits it first, and `useEditState`\n * renders it until the pipeline emits.\n *\n * @internal\n */\nexport function getInitialEditState(\n schema: Schema,\n idPair: IdPair,\n typeName: string,\n): EditStateFor {\n const liveEditSchemaType = isLiveEditEnabled(schema, typeName)\n const scopeId = idPair.versionId ? getVersionFromId(idPair.versionId) : undefined\n\n return {\n id: idPair.publishedId,\n type: typeName,\n draft: null,\n published: null,\n version: null,\n liveEdit: typeof idPair.versionId !== 'undefined' || liveEditSchemaType,\n liveEditSchemaType,\n ready: false,\n transactionSyncLock: null,\n release: scopeId,\n scopeId,\n }\n}\n\n// How long to keep the pipeline alive after the last subscriber unsubscribes.\n// Subscriber churn (e.g. a React commit that unsubscribes every consumer before\n// the replacements subscribe) can momentarily drop the refcount to zero. A bare\n// teardown would make the next subscriber re-enter the cold-start path: the SWR\n// cache replays with `fromCache: true`, which emits `ready: false` and flips the\n// form read-only until fresh snapshots arrive — silently swallowing keystrokes\n// typed in that window. The invariant: a momentary zero-subscriber gap on a\n// warm, healthy document pair must never surface as `ready: false`.\nconst TEARDOWN_GRACE_PERIOD = 1_000\n\n/** @internal */\nexport const editState = memoize(\n (\n ctx: {\n client: SanityClient\n schema: Schema\n /**\n * @deprecated Does nothing. Preserved to avoid breaking changes.\n * Will be removed in the next major version.\n */\n serverActionsEnabled?: Observable<boolean>\n extraOptions?: DocumentStoreExtraOptions\n },\n idPair: IdPair,\n typeName: string,\n ): Observable<EditStateFor> => {\n const initialState = getInitialEditState(ctx.schema, idPair, typeName)\n const {liveEdit, liveEditSchemaType, scopeId} = initialState\n\n return snapshotPair(ctx.client, idPair, typeName, undefined, ctx.extraOptions).pipe(\n switchMap((versions) =>\n combineLatest([\n versions.draft.snapshots$,\n versions.published.snapshots$,\n versions.transactionsPendingEvents$.pipe(\n map((ev: PendingMutationsEvent) => (ev.phase === 'begin' ? LOCKED : NOT_LOCKED)),\n startWith(NOT_LOCKED),\n ),\n typeof versions.version === 'undefined' ? of(null) : versions.version.snapshots$,\n ]),\n ),\n swr(`${idPair.publishedId}-${idPair.draftId}-${idPair.versionId}`),\n measureFirstEmission(\n (durationMs, {fromCache, value: [draftSnapshot, publishedSnapshot, versionSnapshot]}) => {\n ctx.extraOptions?.onDocumentPairLoaded?.({\n durationMs,\n fromCache,\n hasPublished: Boolean(publishedSnapshot),\n hasDraft: Boolean(draftSnapshot),\n hasVersion: Boolean(versionSnapshot),\n })\n },\n ),\n // NOTE: `useEditState` deduplicates emissions downstream using shallow equality on\n // `draft`/`published`/`version` as well as `ready` and `transactionSyncLock`.\n // The map below preserves the snapshot identities and only allocates a new outer\n // wrapper while deriving those additional fields.\n //\n // A regression that clones any of these references — example. `draft: {...draftSnapshot}` — would silently\n // turn that dedupe into a no-op. We have regression tests for this.\n map(\n ({\n value: [draftSnapshot, publishedSnapshot, transactionSyncLock, versionSnapshot],\n fromCache,\n }) => ({\n id: idPair.publishedId,\n type: typeName,\n draft: draftSnapshot,\n published: publishedSnapshot,\n version: typeof idPair.versionId === 'undefined' ? null : versionSnapshot,\n liveEdit,\n liveEditSchemaType,\n ready: !fromCache,\n transactionSyncLock: fromCache ? null : transactionSyncLock,\n release: classifyRelease(versionSnapshot, scopeId),\n scopeId,\n }),\n ),\n startWith(initialState),\n // Unlike `publishReplay(1) + refCount()`, this resets the replay subject\n // when the pipeline is torn down, so a later cold subscriber won't get a\n // stale `ready: true` replayed before the cold-start emissions (and an\n // error won't be replayed forever).\n share({\n connector: () => new ReplaySubject(1),\n resetOnRefCountZero: () => timer(TEARDOWN_GRACE_PERIOD),\n }),\n )\n },\n (ctx, idPair, typeName) => memoizeKeyGen(ctx.client, idPair, typeName),\n)\n","import {type SanityClient} from '@sanity/client'\nimport {\n isGlobalDocumentReference,\n isReference,\n type SanityDocument,\n type Schema,\n type ValidationContext,\n type ValidationMarker,\n type CurrentUser,\n} from '@sanity/types'\nimport {evaluateDocumentObservable} from '@sanity/validation/_internal'\nimport {reduce as reduceJSON} from 'json-reduce'\nimport {\n asyncScheduler,\n combineLatest,\n concat,\n defer,\n from,\n lastValueFrom,\n type Observable,\n of,\n timer,\n} from 'rxjs'\nimport {exhaustMapWithTrailing} from 'rxjs-exhaustmap-with-trailing'\nimport {\n distinct,\n distinctUntilChanged,\n first,\n groupBy,\n map,\n mergeMap,\n scan,\n shareReplay,\n skip,\n throttleTime,\n} from 'rxjs/operators'\n\nimport {type SourceClientOptions} from '../config/types'\nimport {type LocaleSource} from '../i18n/types'\nimport {type DocumentPreviewStore} from '../preview/documentPreviewStore'\nimport {getVersionFromId} from '../util/draftUtils'\nimport {shallowEquals} from '../util/shallowEquals'\n\n/**\n * @hidden\n * @beta */\nexport interface ValidationStatus {\n isValidating: boolean\n validation: ValidationMarker[]\n revision?: string\n}\n\nconst INITIAL_VALIDATION_STATUS: ValidationStatus = {\n isValidating: true,\n validation: [],\n}\n\nfunction findReferenceIds(obj: any): Set<string> {\n return reduceJSON(\n obj,\n (acc, node) => {\n if (isReference(node) && !isGlobalDocumentReference(node)) {\n acc.add(node._ref)\n }\n return acc\n },\n new Set<string>(),\n )\n}\n\nconst EMPTY_VALIDATION: ValidationMarker[] = []\n\ntype GetDocumentExists = NonNullable<ValidationContext['getDocumentExists']>\n\nconst listenDocumentExists = (\n observeDocumentAvailability: DocumentPreviewStore['unstable_observeDocumentPairAvailability'],\n id: string,\n versionId: string | undefined,\n): Observable<boolean> =>\n observeDocumentAvailability(id, {version: versionId}).pipe(\n map(({published, version}) => {\n if (!version?.available && version?.reason === 'VERSION_DELETED') {\n return false\n }\n\n return published.available || version?.available || false\n }),\n )\n\n// throttle delay for referenced document updates (i.e. time between responding to changes in referenced documents)\nconst REF_UPDATE_DELAY = 1000\n\nfunction shareLatestWithRefCount<T>() {\n return shareReplay<T>({bufferSize: 1, refCount: true})\n}\n\n/**\n * @internal\n * Takes an observable of a document and validates it, including any references in the document.\n * */\nexport function validateDocumentWithReferences(\n ctx: {\n getClient: (options: SourceClientOptions) => SanityClient\n observeDocumentPairAvailability: DocumentPreviewStore['unstable_observeDocumentPairAvailability']\n schema: Schema\n i18n: LocaleSource\n currentUser?: Omit<CurrentUser, 'role'> | null\n },\n document$: Observable<SanityDocument | null | undefined>,\n // whether to require all references to exist as published documents\n // set to false to allow references to versions as long they exist in the same bundle\n requirePublishedReferences: boolean,\n): Observable<ValidationStatus> {\n const referenceIds$ = document$.pipe(\n map((document) => findReferenceIds(document)),\n mergeMap((ids) => from(ids)),\n )\n\n const versionId$ = document$.pipe(distinctUntilChanged())\n\n // Note: we only use this to trigger a re-run of validation when a referenced document is published/unpublished\n const referenceExistence$ = combineLatest([versionId$, referenceIds$]).pipe(\n groupBy(([_, referenceId]) => referenceId, {duration: () => timer(1000 * 60 * 30)}),\n mergeMap((refIds$) =>\n refIds$.pipe(\n distinct(),\n mergeMap(([document, referenceId]) => {\n // listen for reference document existence\n // if we're require the referenced document to be published: pass undefined as version id\n // as that will check for existence of published document\n // Otherwise, pass the version of the referencing document\n // to validate that the version exists in the same bundle\n const versionId = requirePublishedReferences\n ? undefined\n : getVersionFromId(document?._id || '')\n return listenDocumentExists(\n ctx.observeDocumentPairAvailability,\n referenceId,\n versionId,\n ).pipe(map((result) => [referenceId, result] as const))\n }),\n ),\n ),\n scan((acc: Record<string, boolean>, [id, result]): Record<string, boolean> => {\n if (acc[id] === result) {\n return acc\n }\n return {...acc, [id]: result}\n }, {}),\n distinctUntilChanged(shallowEquals),\n shareLatestWithRefCount(),\n )\n\n // Provided to individual validation functions to support using existence of a weakly referenced document\n // as part of the validation rule (used by references in place)\n const getDocumentExists: GetDocumentExists = ({id}) =>\n lastValueFrom(\n referenceExistence$.pipe(\n // If the id is not present as key in the `referenceExistence` map it means it's existence status\n // isn't yet loaded, so we want to wait until it is\n first((referenceExistence) => id in referenceExistence),\n map((referenceExistence) => referenceExistence[id]),\n ),\n )\n\n const referenceDocumentUpdates$ = referenceExistence$.pipe(\n // we'll skip the first emission since the document already gets an initial validation pass\n // we're only interested in updates in referenced documents after that\n skip(1),\n throttleTime(REF_UPDATE_DELAY, asyncScheduler, {leading: true, trailing: true}),\n )\n\n return combineLatest([document$, concat(of(null), referenceDocumentUpdates$)]).pipe(\n map(([document]) => document),\n exhaustMapWithTrailing((document) => {\n return defer(() => {\n if (!document?._type) {\n return of({validation: EMPTY_VALIDATION, isValidating: false})\n }\n return concat(\n of({isValidating: true, revision: document._rev}),\n evaluateDocumentObservable({\n document,\n getClient: ctx.getClient,\n getDocumentExists,\n i18n: ctx.i18n,\n schema: ctx.schema,\n environment: 'studio',\n currentUser: ctx.currentUser,\n }).pipe(map((result) => ({validation: result.markers, isValidating: false}))),\n )\n })\n }),\n scan((acc, next) => ({...acc, ...next}), INITIAL_VALIDATION_STATUS),\n shareLatestWithRefCount(),\n )\n}\n","import {\n type ValidateDocumentWorkspaceOptions,\n validateDocumentWithWorkspace,\n} from '@sanity/validation'\n\nexport {\n validateDocumentWithReferences,\n type ValidationStatus,\n} from './validateDocumentWithReferences'\n\n/** @beta */\nexport type ValidateDocumentOptions = ValidateDocumentWorkspaceOptions\n\n/**\n * Validates a document against the schema in the given workspace.\n *\n * @beta\n */\nexport function validateDocument(options: ValidateDocumentOptions) {\n // oxlint-disable-next-line typescript/no-deprecated -- wraps the compatibility API without deprecating the stable Studio export\n return validateDocumentWithWorkspace(options)\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type CurrentUser, type Schema} from '@sanity/types'\nimport omit from 'lodash-es/omit.js'\nimport {asyncScheduler, combineLatest, type Observable} from 'rxjs'\nimport {distinctUntilChanged, map, shareReplay, throttleTime} from 'rxjs/operators'\n\nimport {type SourceClientOptions} from '../../../config/types'\nimport {type LocaleSource} from '../../../i18n/types'\nimport {type DraftsModelDocumentAvailability} from '../../../preview/types'\nimport {type DocumentVariantType} from '../../../util/getDocumentVariantType'\nimport {shallowEquals} from '../../../util/shallowEquals'\nimport {validateDocumentWithReferences, type ValidationStatus} from '../../../validation'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {editState} from './editState'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// throttle delay for document updates (i.e. time between responding to changes in the current document)\nconst DOC_UPDATE_DELAY = 200\n\nfunction shareLatestWithRefCount<T>() {\n return shareReplay<T>({bufferSize: 1, refCount: true})\n}\n\n/** @internal */\nexport const validation = memoize(\n (\n ctx: {\n client: SanityClient\n getClient: (options: SourceClientOptions) => SanityClient\n observeDocumentPairAvailability: (id: string) => Observable<DraftsModelDocumentAvailability>\n schema: Schema\n i18n: LocaleSource\n /**\n * @deprecated Does nothing. Preserved to avoid breaking changes.\n * Will be removed in the next major version.\n */\n serverActionsEnabled?: Observable<boolean>\n pairListenerOptions?: DocumentStoreExtraOptions\n currentUser?: Omit<CurrentUser, 'role'> | null\n },\n {draftId, publishedId, versionId}: IdPair,\n typeName: string,\n validationTarget: DocumentVariantType,\n validatePublishedReferences: boolean,\n ): Observable<ValidationStatus> => {\n const document$ = editState(ctx, {draftId, publishedId, versionId}, typeName).pipe(\n map((state) => {\n const {version, draft, published} = state\n\n if (validationTarget === 'draft') return draft\n if (validationTarget === 'version') return version\n return published\n }),\n throttleTime(DOC_UPDATE_DELAY, asyncScheduler, {trailing: true}),\n )\n\n const documentToValidate$ = document$.pipe(\n distinctUntilChanged((prev, next) => {\n if (prev?._rev === next?._rev) {\n return true\n }\n // _rev and _updatedAt may change without other fields changing (due to a limitation in mutator)\n // so only pass on documents if _other_ attributes changes\n return shallowEquals(omit(prev, '_rev', '_updatedAt'), omit(next, '_rev', '_updatedAt'))\n }),\n shareLatestWithRefCount(),\n )\n\n /**\n * When a local mutation is applied, the document content updates immediately\n * but the `_rev` stays the same. When the server later confirms the\n * mutation, a new `_rev` arrives, but since the content hasn't changed (it was\n * already applied), `documentToValidate$` correctly skips re-validation due to\n * the `shallowEquals` check above.\n *\n * However, the `revision` field exposed in `ValidationStatus` must still reflect\n * the latest `_rev` from the server. If it doesn't, consumers that compare\n * `validationStatus.revision` against the current document `_rev` (e.g. the\n * publish action's scheduled-publish guard) will see a stale revision and may\n * never consider validation \"complete\" for the current document state.\n *\n * To fix this, we track `documentRevision$` separately from `documentToValidate$`\n * and always override the revision in the emitted validation status.\n */\n const documentRevision$ = document$.pipe(map((document) => document?._rev))\n\n return combineLatest([\n documentRevision$,\n validateDocumentWithReferences(ctx, documentToValidate$, validatePublishedReferences),\n ]).pipe(\n map(([revision, validationStatus]) => {\n return {...validationStatus, revision}\n }),\n )\n },\n (ctx, idPair, typeName, validationTarget, validatePublishedReferences) => {\n // Use the actual document ID being validated in the cache key for explicitness\n const documentId =\n validationTarget === 'draft'\n ? idPair.draftId\n : validationTarget === 'version'\n ? idPair.versionId\n : idPair.publishedId\n // Include the user id so an in-place user switch gets its own cache entry;\n // the module-level memo cache is never cleared, so without this a new user\n // would replay the previous user's validation result.\n const userId = ctx.currentUser?.id ?? ''\n return `${memoizeKeyGen(ctx.client, idPair, typeName)}-${documentId}-${validatePublishedReferences}-${userId}`\n },\n)\n","import {type InitialValueResolverContext, type SanityDocumentLike, type Schema} from '@sanity/types'\nimport {from, merge, type Observable, of} from 'rxjs'\nimport {\n catchError,\n debounceTime,\n distinctUntilChanged,\n filter,\n map,\n scan,\n startWith,\n switchMap,\n timeout,\n} from 'rxjs/operators'\n\nimport {type DocumentPreviewStore} from '../../../preview/documentPreviewStore'\nimport {RESOLVE_INITIAL_VALUE_TIMEOUT_MS, resolveInitialValue} from '../../../templates/resolve'\nimport {type Template} from '../../../templates/types'\nimport {getDraftId, getPublishedId} from '../../../util/draftUtils'\nimport {\n type InitialValueErrorMsg,\n type InitialValueLoadingMsg,\n type InitialValueMsg,\n type InitialValueSuccessMsg,\n} from './types'\n\n/**\n * @hidden\n * @beta */\nexport interface InitialValueOptions {\n documentId: string\n documentType: string\n templateName?: string\n templateParams?: Record<string, any>\n}\n\nconst LOADING_MSG: InitialValueLoadingMsg = {type: 'loading'}\n\n/**\n * @internal\n */\nexport function getInitialValueStream(\n schema: Schema,\n initialValueTemplates: Template[],\n documentPreviewStore: DocumentPreviewStore,\n opts: InitialValueOptions,\n context: InitialValueResolverContext,\n): Observable<InitialValueMsg> {\n const draft$ = documentPreviewStore.observePaths(\n {_type: 'reference', _ref: getDraftId(opts.documentId)},\n ['_type'],\n )\n\n const published$ = documentPreviewStore.observePaths(\n {_type: 'reference', _ref: getPublishedId(opts.documentId)},\n ['_type'],\n )\n\n const value$ = merge(\n draft$.pipe(map((draft) => ({draft}))),\n published$.pipe(map((published) => ({published}))),\n ).pipe(\n scan((prev, res) => ({...prev, ...res}), {}),\n // Wait until we know the state of both draft and published\n filter((res) => 'draft' in res && 'published' in res),\n map((res: any) => res.draft || res.published),\n // Only update if we didn't previously have a document but we now do\n distinctUntilChanged((prev, next) => Boolean(prev) !== Boolean(next)),\n // Prevent rapid re-resolving when transitioning between different templates\n debounceTime(25),\n )\n\n return value$.pipe(\n switchMap((document): Observable<InitialValueMsg> => {\n // Already exists, so no initial value is needed\n if (document) {\n return of({type: 'success', value: null})\n }\n\n if (!opts.templateName) {\n // @todo: Make sure this is the correct behavior\n return of({type: 'success', value: null})\n }\n\n const template = initialValueTemplates.find((t) => t.id === opts.templateName)\n\n if (!template) {\n console.warn('Template \"%s\" not defined, using empty initial value', opts.templateName)\n return of({type: 'success', value: null})\n }\n\n const resolved$ = from(\n resolveInitialValue(schema, template, opts.templateParams, context),\n ).pipe(\n // A resolver whose request is parked (network/CORS) never settles —\n // time it out so the failure surfaces rather than hanging the editor.\n timeout({first: RESOLVE_INITIAL_VALUE_TIMEOUT_MS}),\n map((initialValue): InitialValueSuccessMsg => ({\n type: 'success',\n // The resolver returns an arbitrary record; by contract it's a\n // document-like value (the template's `_type` was merged in).\n value: initialValue as SanityDocumentLike,\n })),\n catchError((resolveError: Error) => {\n // oxlint-disable no-console\n console.group('Failed to resolve initial value')\n console.error(resolveError)\n console.error('Template ID: %s', opts.templateName)\n console.error('Parameters: %o', opts.templateParams)\n console.groupEnd()\n // oxlint-enable no-console\n\n // Carry the original error so the consumer can classify it\n // (a network/5xx failure in a resolver's `client.fetch` is\n // delegated to the studio's request-error dialog) and re-throwing\n // resolver bugs stay caller-domain.\n const msg: InitialValueErrorMsg = {type: 'error', error: resolveError}\n return of(msg)\n }),\n )\n\n return merge(of<InitialValueMsg>(LOADING_MSG), resolved$)\n }),\n\n startWith(LOADING_MSG),\n distinctUntilChanged(),\n )\n}\n","import {type ClientPerspective, type SanityClient} from '@sanity/client'\nimport {asyncScheduler, defer, merge, type Observable, of, partition, throwError, timer} from 'rxjs'\nimport {exhaustMapWithTrailing} from 'rxjs-exhaustmap-with-trailing'\nimport {filter, mergeMap, share, take, throttleTime} from 'rxjs/operators'\n\nimport {versionedClient} from '../../studioClient'\nimport {variantApiVersion} from '../../variants/util/variantApiVersion'\nimport {type MutationEvent, type ReconnectEvent, type WelcomeEvent} from './types'\n\n/** @internal */\nexport type ListenQueryParams = Record<string, string | number | boolean | string[]>\n\n/**\n * @hidden\n * @beta */\nexport interface ListenQueryOptions {\n tag?: string\n apiVersion?: string\n perspective?: ClientPerspective\n /**\n * The selected editing variant as a bare variant id. When set, documents are resolved as seen\n * through that variant, on top of `perspective`.\n */\n variant?: string\n throttleTime?: number\n transitions?: ('update' | 'appear' | 'disappear')[]\n}\n\nconst fetch = (\n client: SanityClient,\n query: string,\n params: ListenQueryParams,\n options: ListenQueryOptions,\n) =>\n defer(() =>\n versionedClient(client, variantApiVersion(options.variant)).observable.fetch(query, params, {\n tag: options.tag,\n filterResponse: true,\n perspective: options.perspective,\n variant: options.variant,\n }),\n )\n\nconst listen = (\n client: SanityClient,\n query: string,\n params: ListenQueryParams,\n options: ListenQueryOptions,\n) =>\n defer(() =>\n client.listen(query, params, {\n events: ['welcome', 'mutation', 'reconnect'],\n includeResult: false,\n visibility: 'query',\n includeAllVersions: true,\n tag: options.tag,\n }),\n ) as Observable<ReconnectEvent | WelcomeEvent | MutationEvent>\n\nfunction isWelcomeEvent(\n event: MutationEvent | ReconnectEvent | WelcomeEvent,\n): event is WelcomeEvent {\n return event.type === 'welcome'\n}\n\n/** @internal */\nexport function listenQuery(\n client: SanityClient,\n query: string | {fetch: string; listen: string},\n params: ListenQueryParams = {},\n options: ListenQueryOptions = {},\n): Observable<any> {\n const fetchQuery = typeof query === 'string' ? query : query.fetch\n const listenerQuery = typeof query === 'string' ? query : query.listen\n\n const events$ = listen(client, listenerQuery, params, options).pipe(\n mergeMap((ev, i) => {\n const isFirst = i === 0\n if (isFirst && !isWelcomeEvent(ev)) {\n // if the first event is not welcome, it is most likely a reconnect and\n // if it's not a reconnect something is very wrong\n return throwError(\n () =>\n new Error(\n ev.type === 'reconnect'\n ? 'Could not establish EventSource connection'\n : `Received unexpected type of first event \"${ev.type}\"`,\n ),\n )\n }\n return of(ev)\n }),\n share(),\n )\n\n const [welcome$, mutationAndReconnect$] = partition(events$, isWelcomeEvent)\n const isRelevantEvent = (event: MutationEvent | ReconnectEvent | WelcomeEvent): boolean => {\n if (!options.transitions || event.type !== 'mutation') {\n return true\n }\n\n return options.transitions.includes(event.transition)\n }\n\n const doFetch = () => fetch(client, fetchQuery, params, options)\n\n return merge(\n welcome$.pipe(take(1)),\n mutationAndReconnect$.pipe(\n filter(isRelevantEvent),\n throttleTime(options.throttleTime || 1000, asyncScheduler, {leading: true, trailing: true}),\n ),\n ).pipe(\n exhaustMapWithTrailing((event) => {\n if (event.type === 'mutation' && event.visibility !== 'query') {\n // Even though the listener request specifies visibility=query, the events are not guaranteed to be delivered with visibility=query\n // If the event we are responding to arrives with visibility != query, we add a little delay to allow for the updated document to be available for queries\n // See https://www.sanity.io/docs/listening#visibility-c4786e55c3ff\n return timer(1200).pipe(mergeMap(doFetch))\n }\n return doFetch()\n }),\n )\n}\n","import {type DocumentPairTarget} from './types'\n\n/**\n * Normalizes the `version` parameter accepted by the document pair APIs\n * (`useDocumentOperation`, `pair.editOperations`) to a {@link DocumentPairTarget}.\n *\n * A bare string is back-compat shorthand for a plain version target — the scope id, i.e. the\n * `<scopeId>` segment of `versions.<scopeId>.<groupId>` (a release or agent/anonymous bundle\n * name); target objects pass through by reference, and `undefined` means the base\n * draft/published pair.\n *\n */\nexport function normalizeDocumentPairTarget(\n version: string | DocumentPairTarget | undefined,\n): DocumentPairTarget | undefined {\n if (typeof version === 'string') {\n return {kind: 'version', scopeId: version}\n }\n return version\n}\n\n/**\n * The scope id (the `<scopeId>` segment of `versions.<scopeId>.<groupId>`) the pair should check\n * out for a target, or `undefined` when the base draft/published pair applies. Guarded kinds\n * (`target-missing`, `unresolved`) never reach pair checkout and yield `undefined`.\n *\n */\nexport function getPairTargetScopeId(target: DocumentPairTarget | undefined): string | undefined {\n if (target?.kind === 'version' || target?.kind === 'variant') {\n return target.scopeId\n }\n return undefined\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type Observable, of} from 'rxjs'\n\nimport {getPublishedId} from '../../util/draftUtils'\n\nexport function resolveTypeForDocument(\n client: SanityClient,\n id: string,\n specifiedType = '*',\n): Observable<string> {\n // if is resolved document type\n if (specifiedType && specifiedType !== '*') {\n return of(specifiedType)\n }\n\n const query = '*[sanity::versionOf($publishedId)][0]._type'\n\n return client.observable.fetch(\n query,\n {publishedId: getPublishedId(id)},\n {\n tag: 'document.resolve-type',\n },\n )\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type CurrentUser, type InitialValueResolverContext, type Schema} from '@sanity/types'\nimport {type Observable, of} from 'rxjs'\nimport {filter, map} from 'rxjs/operators'\n\nimport {type SourceClientOptions} from '../../config/types'\nimport {type LocaleSource} from '../../i18n/types'\nimport {type DocumentPreviewStore} from '../../preview/documentPreviewStore'\nimport {DEFAULT_STUDIO_CLIENT_OPTIONS} from '../../studioClient'\nimport {type Template} from '../../templates/types'\nimport {\n getPublishedId,\n getVersionFromId,\n isDraftId,\n isVersionId,\n getIdPair,\n} from '../../util/draftUtils'\nimport {getDocumentVariantType} from '../../util/getDocumentVariantType'\nimport {type ValidationStatus} from '../../validation'\nimport {type HistoryStore} from '../history/createHistoryStore'\nimport {\n checkoutPair,\n type CommitError,\n type DocumentVersionEvent,\n type Pair,\n} from './document-pair/checkoutPair'\nimport {commitErrorStatus} from './document-pair/commitErrorStatus'\nimport {consistencyStatus} from './document-pair/consistencyStatus'\nimport {documentEvents} from './document-pair/documentEvents'\nimport {editOperations} from './document-pair/editOperations'\nimport {editState, type EditStateFor} from './document-pair/editState'\nimport {\n type OperationError,\n operationEvents,\n type OperationSuccess,\n} from './document-pair/operationEvents'\nimport {GUARDED, TARGET_NOT_FOUND_OPERATIONS} from './document-pair/operations/helpers'\nimport {type OperationsAPI} from './document-pair/operations/types'\nimport {validation} from './document-pair/validation'\nimport {type DocumentStoreExtraOptions} from './getPairListener'\nimport {getInitialValueStream, type InitialValueOptions} from './initialValue/initialValue'\nimport {type InitialValueMsg} from './initialValue/types'\nimport {listenQuery, type ListenQueryOptions} from './listenQuery'\nimport {getPairTargetScopeId, normalizeDocumentPairTarget} from './normalizeDocumentPairTarget'\nimport {resolveTypeForDocument} from './resolveTypeForDocument'\nimport {type DocumentPairTarget, type IdPair} from './types'\n\n/**\n * @hidden\n * @beta */\nexport type QueryParams = Record<string, string | number | boolean | string[]>\n\nfunction getIdPairFromPublished(publishedId: string, version?: string): IdPair {\n if (version === 'published' || version === 'drafts') {\n throw new Error('Version Id cannot be \"published\" or \"drafts\"')\n }\n if (isVersionId(publishedId)) {\n throw new Error('editOpsOf does not expect a version id.')\n }\n if (isDraftId(publishedId)) {\n throw new Error('editOpsOf does not expect a draft id.')\n }\n\n return getIdPair(publishedId, {version})\n}\n\n/**\n * @hidden\n * @beta */\nexport interface DocumentStore {\n /**\n * Checks out a document (with its published and draft version) for real-time editing.\n * Note that every call to this function will open a new listener to the server.\n * It's recommended to use the helper functions on `pair` below which will re-use a single connection.\n *\n * @internal\n **/\n checkoutPair: (idPair: IdPair) => Pair\n initialValue: (\n opts: InitialValueOptions,\n context: InitialValueResolverContext,\n ) => Observable<InitialValueMsg>\n listenQuery: (\n query: string | {fetch: string; listen: string},\n params: QueryParams,\n options: ListenQueryOptions,\n ) => Observable<any>\n resolveTypeForDocument: (id: string, specifiedType?: string) => Observable<string>\n\n pair: {\n /** @internal */\n commitErrorStatus: (\n publishedId: string,\n type: string,\n version?: string,\n ) => Observable<CommitError | undefined>\n consistencyStatus: (publishedId: string, type: string, version?: string) => Observable<boolean>\n /** @internal */\n documentEvents: (\n publishedId: string,\n type: string,\n version?: string,\n ) => Observable<DocumentVersionEvent>\n /**\n * @internal\n * `version` accepts either a plain version name (release/bundle) or a\n * {@link DocumentPairTarget}. The guarded target kinds (`unresolved`, `target-missing`) emit\n * a disabled operations API without checking out a pair, so operations can never reach the\n * base draft/published pair while a selected target is unresolved or has no document.\n */\n editOperations: (\n publishedId: string,\n type: string,\n version?: string | DocumentPairTarget,\n ) => Observable<OperationsAPI>\n editState: (publishedId: string, type: string, version?: string) => Observable<EditStateFor>\n operationEvents: (\n publishedId: string,\n type: string,\n ) => Observable<OperationSuccess | OperationError>\n validation: (\n validationTargetId: string,\n type: string,\n // Whether to require referenced documents to be published\n // if `true`, any reference to a document that's not published will yield a validation error\n // if `false`, any reference to a non-published document is ok as long as it's in the same bundle\n // as the document we're validating\n validatePublishedReferences: boolean,\n ) => Observable<ValidationStatus>\n }\n}\n\n/** @internal */\nexport interface DocumentStoreOptions {\n getClient: (options: SourceClientOptions) => SanityClient\n documentPreviewStore: DocumentPreviewStore\n historyStore: HistoryStore\n schema: Schema\n initialValueTemplates: Template[]\n i18n: LocaleSource\n /**\n * @deprecated Does nothing. Preserved to avoid breaking changes.\n * Will be removed in the next major version.\n */\n serverActionsEnabled?: Observable<boolean>\n extraOptions?: DocumentStoreExtraOptions\n currentUser?: Omit<CurrentUser, 'role'> | null\n}\n\n/** @internal */\nexport function createDocumentStore({\n getClient,\n documentPreviewStore,\n historyStore,\n initialValueTemplates,\n schema,\n i18n,\n extraOptions = {},\n currentUser,\n}: DocumentStoreOptions): DocumentStore {\n const observeDocumentPairAvailability =\n documentPreviewStore.unstable_observeDocumentPairAvailability\n\n // Note that we're both passing a shared `client` here which is used by the\n // internal operations, and a `getClient` method that we expose to user-land\n // for things like validations\n const client = getClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n\n const {\n onSyncErrorRecovery,\n onReportLatency,\n onSlowCommit,\n onReportMutationPerformance,\n onDocumentRebase,\n } = extraOptions\n const ctx = {\n client,\n getClient,\n observeDocumentPairAvailability,\n historyStore,\n schema,\n i18n,\n extraOptions,\n currentUser,\n }\n\n return {\n // Public API\n checkoutPair(idPair) {\n return checkoutPair(client, idPair, undefined, {\n onSyncErrorRecovery,\n onReportLatency,\n onSlowCommit,\n onReportMutationPerformance,\n onDocumentRebase,\n })\n },\n initialValue(opts, context) {\n return getInitialValueStream(\n schema,\n initialValueTemplates,\n documentPreviewStore,\n opts,\n context,\n )\n },\n listenQuery(query, params, listenQueryOptions) {\n return listenQuery(client, query, params, listenQueryOptions)\n },\n resolveTypeForDocument(id, specifiedType) {\n return resolveTypeForDocument(client, id, specifiedType)\n },\n pair: {\n commitErrorStatus(publishedId, type, version) {\n return commitErrorStatus(\n ctx.client,\n getIdPairFromPublished(publishedId, version),\n type,\n extraOptions,\n )\n },\n consistencyStatus(publishedId, type, version) {\n return consistencyStatus(\n ctx.client,\n getIdPairFromPublished(publishedId, version),\n type,\n extraOptions,\n )\n },\n documentEvents(publishedId, type, version) {\n return documentEvents(\n ctx.client,\n getIdPairFromPublished(publishedId, version),\n type,\n extraOptions,\n )\n },\n editOperations(publishedId, type, version) {\n const target = normalizeDocumentPairTarget(version)\n\n // Guarded targets never check out a pair. Branching here (before the memoized\n // `editOperations`) also keeps them out of `memoizeKeyGen`, which only keys on\n // `publishedId + versionId` and would collide these with the base pair.\n if (target?.kind === 'unresolved') {\n return of(GUARDED)\n }\n if (target?.kind === 'target-missing') {\n return of(TARGET_NOT_FOUND_OPERATIONS)\n }\n\n return editOperations(\n ctx,\n getIdPairFromPublished(publishedId, getPairTargetScopeId(target)),\n type,\n target,\n )\n },\n editState(publishedId, type, version) {\n const idPair = getIdPairFromPublished(publishedId, version)\n\n const edit = editState(ctx, idPair, type)\n return edit\n },\n operationEvents(publishedId, type) {\n return operationEvents({\n client,\n historyStore,\n schema,\n extraOptions,\n }).pipe(\n filter(\n (result) =>\n result.args.idPair.publishedId === publishedId && result.args.typeName === type,\n ),\n map((result): OperationSuccess | OperationError => {\n const {operationName, idPair} = result.args\n return result.type === 'success'\n ? {\n type: 'success',\n op: operationName,\n id: idPair.publishedId,\n idPair,\n }\n : {\n type: 'error',\n op: operationName,\n id: idPair.publishedId,\n error: result.error,\n idPair,\n }\n }),\n )\n },\n validation(validationTargetId, type, requirePublishedReferences) {\n const publishedId = getPublishedId(validationTargetId)\n const idPair = getIdPair(publishedId, {version: getVersionFromId(validationTargetId)})\n const validationTarget = getDocumentVariantType(validationTargetId)\n return validation(ctx, idPair, type, validationTarget, requirePublishedReferences)\n },\n },\n }\n}\n","import { asapScheduler, NEVER, Subject, timer, using, } from \"rxjs\";\r\nimport { scan, switchMap, tap } from \"rxjs/operators\";\r\nexport function refCountDelay(duration, scheduler = asapScheduler) {\r\n return (source) => {\r\n const connectable = source;\r\n let connectableSubscription = null;\r\n let connectorSubscription = null;\r\n const notifier = new Subject();\r\n const connector = notifier.pipe(scan((count, step) => count + step, 0), switchMap((count) => {\r\n if (count === 0) {\r\n return timer(duration, scheduler).pipe(tap(() => {\r\n if (connectableSubscription) {\r\n connectableSubscription.unsubscribe();\r\n connectableSubscription = null;\r\n }\r\n if (connectorSubscription) {\r\n connectorSubscription.unsubscribe();\r\n connectorSubscription = null;\r\n }\r\n }));\r\n }\r\n if (!connectableSubscription && count > 0) {\r\n return timer(0, scheduler).pipe(tap(() => {\r\n if (!connectableSubscription) {\r\n connectableSubscription = connectable.connect();\r\n }\r\n }));\r\n }\r\n return NEVER;\r\n }));\r\n return using(() => {\r\n if (!connectorSubscription) {\r\n connectorSubscription = connector.subscribe();\r\n }\r\n notifier.next(1);\r\n return { unsubscribe: () => notifier.next(-1) };\r\n }, () => source);\r\n };\r\n}\r\nexport const refCountAuditTime = refCountDelay;\r\n//# sourceMappingURL=refCountDelay.js.map","import {concat, fromEvent, of} from 'rxjs'\nimport {distinctUntilChanged, map} from 'rxjs/operators'\n\nconst DEBUG_PREFIX = '_debug_'\n\nconst hashchange$ = typeof window === 'undefined' ? of({}) : fromEvent(window, 'hashchange')\n\nexport const debugParams$ = concat(of(0), hashchange$).pipe(\n map(() => (typeof document === 'undefined' ? '#' : document.location.hash)),\n distinctUntilChanged(),\n map((hash) =>\n hash\n .slice(1)\n .split(';')\n .filter((p) => p.toLowerCase().startsWith(DEBUG_PREFIX))\n .map((param) => param.slice(DEBUG_PREFIX.length)),\n ),\n)\n\nexport const debugRolesParam$ = debugParams$.pipe(\n map((args) => args.find((arg) => arg.startsWith('roles='))),\n map(\n (arg) =>\n arg\n ?.split('roles=')[1]\n .split(',')\n .map((r) => r.trim()) || [],\n ),\n)\n","// NOTE: these example grants are used in other test files.\n// if you change this file, check to see if other files need to be updated too\nimport {type Grant} from '../types'\n\nexport const administrator: Grant[] = [\n {\n filter: '_id in path(\"**\")',\n permissions: ['read', 'create', 'history', 'update'],\n },\n]\n\nexport const editor: Grant[] = [\n {\n filter: '_id in path(\"**\")',\n permissions: ['read', 'create', 'history', 'update'],\n },\n]\n\nexport const developer: Grant[] = [\n {\n filter: '_id in path(\"**\")',\n permissions: ['read', 'create', 'history', 'update'],\n },\n]\n\nexport const contributor: Grant[] = [\n {\n filter: '_id in path(\"**\")',\n permissions: ['read'],\n },\n {\n filter: '_id in path(\"drafts.**\")',\n permissions: ['create', 'history', 'update'],\n },\n]\n\nexport const viewer: Grant[] = [\n {\n filter: '_id in path(\"**\")',\n permissions: ['read', 'history'],\n },\n]\n\nexport const requiresApproval: Grant[] = [\n {\n filter: '!locked',\n permissions: ['read', 'create', 'update'],\n },\n]\n\nexport const restricted: Grant[] = [\n {\n filter:\n '_id in path(\"drafts.**\") && _type in [\"stringsTest\", \"book\", \"author\", \"referenceTest\"]',\n permissions: ['read', 'create', 'history', 'update'],\n },\n {\n filter: '_id in path(\"**\")',\n permissions: ['read'],\n },\n]\n","import {map} from 'rxjs/operators'\n\nimport {debugRolesParam$} from '../../debugParams/debugParams'\nimport {type Grant} from '../types'\nimport * as grants from './exampleGrants'\nimport {type ExampleRoleName} from './exampleRoles'\n\nconst DEBUG_ROLE_GRANTS_MAP: Record<ExampleRoleName, Grant[]> = {\n // basic\n administrator: grants.administrator,\n editor: grants.editor,\n developer: grants.developer,\n contributor: grants.contributor,\n viewer: grants.viewer,\n\n // custom\n restricted: grants.restricted,\n requiresApproval: grants.requiresApproval,\n\n // legacy\n read: grants.viewer,\n write: grants.editor,\n}\n\n// todo: merge other resource keys(?)\nexport const debugGrants$ = debugRolesParam$.pipe(\n map((roles) => {\n if (!roles.length) return null\n\n return roles\n .filter((value) => Boolean(value) && value in DEBUG_ROLE_GRANTS_MAP)\n .flatMap((roleName: ExampleRoleName) => DEBUG_ROLE_GRANTS_MAP[roleName] || [])\n }),\n)\n","import {type SanityClient} from '@sanity/client'\nimport {type CurrentUser, type SanityDocument} from '@sanity/types'\nimport {evaluate, parse} from 'groq-js'\nimport {defer, of} from 'rxjs'\nimport {refCountDelay} from 'rxjs-etc/operators'\nimport {distinctUntilChanged, publishReplay, switchMap} from 'rxjs/operators'\n\nimport {shallowEquals} from '../../util/shallowEquals'\nimport {type StoreRequestErrorHandler} from '../requestErrorHandler'\nimport {debugGrants$} from './debug'\nimport {\n type DocumentValuePermission,\n type EvaluationParams,\n type Grant,\n type GrantsStore,\n type PermissionCheckResult,\n} from './types'\n\nasync function getDatasetGrants(\n client: SanityClient,\n projectId: string,\n dataset: string,\n errorHandler: StoreRequestErrorHandler | undefined,\n): Promise<Grant[]> {\n // `acl` stands for access control list and returns a list of grants\n const fetchGrants = () =>\n client.request<Grant[]>({\n url: `/projects/${projectId}/datasets/${dataset}/acl`,\n tag: 'acl.get',\n })\n\n // Every permission check depends on this read, so there is no local\n // recovery if it fails — delegate failures to the error handler when one\n // is provided. Retryable: it's an idempotent GET, safe to re-run.\n return errorHandler ? errorHandler.attempt(fetchGrants, {retryable: true}) : fetchGrants()\n}\n\nfunction getParams(userId: string | null): EvaluationParams {\n const params: EvaluationParams = {}\n\n if (userId !== null) {\n params.identity = userId\n }\n\n return params\n}\n\nconst PARSED_FILTERS_MEMO = new Map()\nasync function matchesFilter(userId: string | null, filter: string, document: SanityDocument) {\n if (!PARSED_FILTERS_MEMO.has(filter)) {\n // note: it might be tempting to also memoize the result of the evaluation here,\n // Currently these filters are typically evaluated whenever a document change, which means they will be evaluated\n // quite frequently with different versions of the document. There might be some gains in finding out which subset of document\n // properties to use as key (e.g. by looking at the parsed filter and see what properties the filter cares about)\n // But as always, it's worth considering if the complexity/memory usage is worth the potential perf gain…\n PARSED_FILTERS_MEMO.set(filter, parse(`*[${filter}]`))\n }\n const parsed = PARSED_FILTERS_MEMO.get(filter)\n\n const evalParams = getParams(userId)\n const {identity} = evalParams\n const params: Record<string, unknown> = {...evalParams}\n const data = await (await evaluate(parsed, {dataset: [document], identity, params})).get()\n return data?.length === 1\n}\ninterface GrantsStoreOptionsCurrentUser {\n client: SanityClient\n /**\n * Optional handler for failures of requests made by the store. When\n * omitted, request failures propagate to the permission streams.\n */\n errorHandler?: StoreRequestErrorHandler\n /**\n * @deprecated The `currentUser` option is deprecated. Use `userId` instead.\n */\n currentUser: CurrentUser | null\n}\n\ninterface GrantsStoreOptionsUserId {\n client: SanityClient\n /**\n * Optional handler for failures of requests made by the store. When\n * omitted, request failures propagate to the permission streams.\n */\n errorHandler?: StoreRequestErrorHandler\n userId: string | null\n}\n\n/** @internal */\nexport type GrantsStoreOptions = GrantsStoreOptionsCurrentUser | GrantsStoreOptionsUserId\n\n/** @internal */\nexport function createGrantsStore(opts: GrantsStoreOptions): GrantsStore {\n const {client, errorHandler} = opts\n const versionedClient = client.withConfig({apiVersion: '2021-06-07'})\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const userId = 'userId' in opts ? opts.userId : opts?.currentUser?.id || null\n\n const datasetGrants$ = defer(() => of(versionedClient.config())).pipe(\n switchMap(({projectId, dataset}) => {\n if (!projectId || !dataset) {\n throw new Error('Missing projectId or dataset')\n }\n return getDatasetGrants(versionedClient, projectId, dataset, errorHandler)\n }),\n )\n\n const currentUserDatasetGrants = debugGrants$.pipe(\n switchMap((debugGrants) => (debugGrants ? of(debugGrants) : datasetGrants$)),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n refCountDelay(1000),\n )\n\n return {\n checkDocumentPermission(permission: DocumentValuePermission, document: SanityDocument) {\n return currentUserDatasetGrants.pipe(\n switchMap((grants) => grantsPermissionOn(userId, grants, permission, document)),\n distinctUntilChanged(shallowEquals),\n )\n },\n }\n}\n\n/**\n * @internal\n * Takes a grants object, a permission and a document\n * checks whether the permission is granted for the given document\n */\nexport async function grantsPermissionOn(\n userId: string | null,\n grants: Grant[],\n permission: DocumentValuePermission,\n document: SanityDocument | null,\n): Promise<PermissionCheckResult> {\n if (!document) {\n // we say it's granted if null due to initial states\n return {granted: true, reason: 'Null document, nothing to check'}\n }\n\n if (!grants.length) {\n return {granted: false, reason: 'No document grants'}\n }\n\n const matchingGrants: Grant[] = []\n\n for (const grant of grants) {\n if (await matchesFilter(userId, grant.filter, document)) {\n matchingGrants.push(grant)\n }\n }\n\n const foundMatch = matchingGrants.some((grant) => grant.permissions.some((p) => p === permission))\n\n return {\n granted: foundMatch,\n reason: foundMatch ? `Matching grant` : `No matching grants found`,\n }\n}\n","/** @internal */\nexport const isDev = process.env.NODE_ENV !== 'production'\n\n/** @internal */\nexport const isProd = !isDev\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type MendozaEffectPair, type MendozaPatch} from '@sanity/types'\n\nimport {type Chunk, type ChunkType} from '../../../field/types'\nimport {type Transaction} from './types'\n\nfunction canMergeEdit(type: ChunkType) {\n return type === 'create' || type === 'editDraft'\n}\n\nconst CHUNK_WINDOW = 5 * 60 * 1000 // 5 minutes\n\nfunction isWithinMergeWindow(a: string, b: string) {\n return Date.parse(b) - Date.parse(a) < CHUNK_WINDOW\n}\n\nexport function mergeChunk(left: Chunk, right: Chunk): Chunk | [Chunk, Chunk] {\n if (left.end !== right.start) throw new Error('chunks are not next to each other')\n\n // TODO: How to detect first squash/create\n\n const draftState = combineState(left.draftState, right.draftState)\n const publishedState = combineState(left.publishedState, right.publishedState)\n\n if (left.type === 'delete' && right.type === 'editDraft') {\n return [left, {...right, type: 'create', draftState, publishedState}]\n }\n\n // Convert deletes into either discardDraft or unpublish depending on what's been deleted.\n if (right.type === 'delete') {\n if (draftState === 'missing' && publishedState === 'present') {\n return [left, {...right, type: 'discardDraft', draftState, publishedState}]\n }\n\n if (draftState === 'present' && publishedState === 'missing') {\n return [left, {...right, type: 'unpublish', draftState, publishedState}]\n }\n }\n\n if (\n canMergeEdit(left.type) &&\n right.type === 'editDraft' &&\n isWithinMergeWindow(left.endTimestamp, right.startTimestamp)\n ) {\n const authors = new Set<string>()\n for (const author of left.authors) authors.add(author)\n for (const author of right.authors) authors.add(author)\n\n return {\n index: 0,\n id: right.id,\n type: left.type,\n start: left.start,\n end: right.end,\n startTimestamp: left.startTimestamp,\n endTimestamp: right.endTimestamp,\n authors,\n draftState,\n publishedState,\n }\n }\n\n return [left, {...right, draftState, publishedState}]\n}\n\ntype ChunkState = 'unedited' | 'deleted' | 'upsert'\nfunction getChunkState(effect?: MendozaEffectPair): ChunkState {\n const modified = Boolean(effect)\n const deleted = effect && isDeletePatch(effect?.apply)\n\n if (deleted) {\n return 'deleted'\n }\n\n if (modified) {\n return 'upsert'\n }\n\n return 'unedited'\n}\n\n/*\n * getChunkType tries to determine what effect the given transaction had on the document\n * More information about the logic can be found here https://github.com/sanity-io/sanity/pull/2633#issuecomment-886461812\n *\n * | | draft unedited | draft deleted | draft upsert |\n * |--------------------|----------------|---------------|--------------|\n * | published unedited | X | delete | editDraft |\n * | published deleted | delete | delete | delete |\n * | published upsert | liveEdit | publish | liveEdit |\n */\nfunction getChunkType(transaction: Transaction): ChunkType {\n const draftState = getChunkState(transaction.draftEffect)\n const publishedState = getChunkState(transaction.publishedEffect)\n\n if (publishedState === 'unedited') {\n if (draftState === 'deleted') {\n return 'delete'\n }\n\n if (draftState === 'upsert') {\n return 'editDraft'\n }\n }\n\n if (publishedState === 'deleted') {\n return 'delete'\n }\n\n if (publishedState === 'upsert') {\n if (draftState === 'unedited') {\n return 'editLive'\n }\n\n if (draftState === 'deleted') {\n return 'publish'\n }\n\n if (draftState === 'upsert') {\n return 'editLive'\n }\n }\n\n return 'editLive'\n}\n\nexport function chunkFromTransaction(transaction: Transaction): Chunk {\n const modifiedDraft = Boolean(transaction.draftEffect)\n const modifiedPublished = Boolean(transaction.publishedEffect)\n\n const draftDeleted = transaction.draftEffect && isDeletePatch(transaction.draftEffect.apply)\n const publishedDeleted =\n transaction.publishedEffect && isDeletePatch(transaction.publishedEffect.apply)\n\n const type = getChunkType(transaction)\n\n return {\n index: 0,\n id: transaction.id,\n type,\n start: transaction.index,\n end: transaction.index + 1,\n startTimestamp: transaction.timestamp,\n endTimestamp: transaction.timestamp,\n authors: new Set([transaction.author]),\n draftState: modifiedDraft ? (draftDeleted ? 'missing' : 'present') : 'unknown',\n publishedState: modifiedPublished ? (publishedDeleted ? 'missing' : 'present') : 'unknown',\n }\n}\n\nfunction combineState(\n left: 'present' | 'missing' | 'unknown',\n right: 'present' | 'missing' | 'unknown',\n) {\n return right === 'unknown' ? left : right\n}\n\nfunction isDeletePatch(patch: MendozaPatch): boolean {\n return patch[0] === 0 && patch[1] === null\n}\n","import {\n type ArrayInput,\n diffInput,\n type Input,\n type ObjectInput,\n type StringInput,\n wrap,\n} from '@sanity/diff'\nimport {type SanityDocument, type TransactionLogEventWithEffects} from '@sanity/types'\nimport {type incremental} from 'mendoza'\n\nimport {type Annotation} from '../../field/types'\nimport {type DocumentGroupEvent} from './types'\n\nexport type EventMeta = {\n transactionIndex: number\n event?: DocumentGroupEvent\n} | null\n\nfunction isSameAnnotation(a: Annotation, b: Annotation): boolean {\n if (a && b) {\n return a.author === b.author && a.timestamp === b.timestamp\n }\n\n if (!a && !b) {\n return true\n }\n\n return false\n}\n\nexport type AnnotationExtractor<T> = {\n fromValue(value: incremental.Value<T>): Annotation\n fromMeta(meta: T): Annotation\n}\n\nclass ArrayContentWrapper<T> implements ArrayInput<Annotation> {\n type = 'array' as const\n value: unknown[]\n length: number\n annotation: Annotation\n extractor: AnnotationExtractor<T>\n\n private content: incremental.ArrayContent<T>\n private elements: Input<Annotation>[] = []\n\n constructor(\n content: incremental.ArrayContent<T>,\n value: unknown[],\n annotation: Annotation,\n extractor: AnnotationExtractor<T>,\n ) {\n this.content = content\n this.value = value\n this.annotation = annotation\n this.extractor = extractor\n this.length = content.elements.length\n }\n\n at(idx: number) {\n if (idx >= this.length) throw new Error('out of bounds')\n const input = this.elements[idx]\n if (input) {\n return input\n }\n return (this.elements[idx] = wrapValue(\n this.content.elements[idx],\n this.value[idx],\n this.extractor,\n ))\n }\n\n annotationAt(idx: number): Annotation {\n const meta = this.content.metas[idx]\n return this.extractor.fromMeta(meta)\n }\n}\n\nclass ObjectContentWrapper<T> implements ObjectInput<Annotation> {\n type = 'object' as const\n value: Record<string, unknown>\n keys: string[]\n annotation: Annotation\n extractor: AnnotationExtractor<T>\n\n private content: incremental.ObjectContent<T>\n private fields: Record<string, Input<Annotation>> = {}\n\n constructor(\n content: incremental.ObjectContent<T>,\n value: Record<string, unknown>,\n annotation: Annotation,\n extractor: AnnotationExtractor<T>,\n ) {\n this.content = content\n this.value = value\n this.annotation = annotation\n this.extractor = extractor\n this.keys = Object.keys(content.fields)\n }\n\n get(key: string) {\n const input = this.fields[key]\n if (input) {\n return input\n }\n const value = this.content.fields[key]\n if (!value) return undefined\n return (this.fields[key] = wrapValue(value, this.value[key], this.extractor))\n }\n}\n\nclass StringContentWrapper<T> implements StringInput<Annotation> {\n type = 'string' as const\n value: string\n annotation: Annotation\n extractor: AnnotationExtractor<T>\n\n private content: incremental.StringContent<T>\n\n constructor(\n content: incremental.StringContent<T>,\n value: string,\n annotation: Annotation,\n extractor: AnnotationExtractor<T>,\n ) {\n this.content = content\n this.value = value\n this.annotation = annotation\n this.extractor = extractor\n }\n\n sliceAnnotation(start: number, end: number): {text: string; annotation: Annotation}[] {\n const result: {text: string; annotation: Annotation}[] = []\n let idx = 0\n\n function push(text: string, annotation: Annotation) {\n if (result.length > 0) {\n const lst = result[result.length - 1]\n if (isSameAnnotation(lst.annotation, annotation)) {\n lst.text += text\n return\n }\n }\n\n result.push({text, annotation})\n }\n\n for (const part of this.content.parts) {\n const length = part.value.length\n\n const subStart = Math.max(0, start - idx)\n if (subStart < length) {\n // The start of the slice is inside this part somewhere.\n\n // Figure out where the end is:\n const subEnd = Math.min(length, end - idx)\n\n // If the end of the slice is before this part, then we're guaranteed\n // that there are no more parts.\n if (subEnd <= 0) break\n\n push(part.value.slice(subStart, subEnd), this.extractor.fromValue(part))\n }\n\n idx += length\n }\n\n return result\n }\n}\n\nexport function wrapValue<T>(\n value: incremental.Value<T>,\n raw: unknown,\n extractor: AnnotationExtractor<T>,\n): Input<Annotation> {\n const annotation = extractor.fromValue(value)\n\n if (value.content) {\n switch (value.content.type) {\n case 'array':\n return new ArrayContentWrapper<T>(value.content, raw as unknown[], annotation, extractor)\n case 'object':\n return new ObjectContentWrapper<T>(\n value.content,\n raw as Record<string, unknown>,\n annotation,\n extractor,\n )\n case 'string':\n return new StringContentWrapper<T>(value.content, raw as string, annotation, extractor)\n default:\n // do nothing\n }\n }\n\n return wrap(raw, annotation)\n}\n\nfunction extractAnnotationForFromInput(\n transactions: TransactionLogEventWithEffects[],\n meta: EventMeta,\n): Annotation {\n if (meta) {\n // The next transaction is where it disappeared:\n return annotationForTransactionIndex(transactions, meta.transactionIndex + 1, meta.event)\n }\n\n // Fallback: if meta is null, the value existed initially and was changed/removed\n // by the first transaction in our range\n if (transactions.length > 0) {\n return annotationForTransactionIndex(transactions, 0)\n }\n\n return null\n}\nfunction extractAnnotationForToInput(\n transactions: TransactionLogEventWithEffects[],\n meta: EventMeta,\n): Annotation {\n if (meta) {\n return annotationForTransactionIndex(transactions, meta.transactionIndex, meta.event)\n }\n\n return null\n}\n\nfunction annotationForTransactionIndex(\n transactions: TransactionLogEventWithEffects[],\n idx: number,\n event?: DocumentGroupEvent,\n) {\n const tx = transactions[idx]\n if (!tx) return null\n\n return {\n event: event,\n timestamp: tx.timestamp,\n author: tx.author,\n }\n}\n\nexport function diffValue({\n transactions,\n fromValue,\n fromRaw,\n toValue,\n toRaw,\n}: {\n transactions: TransactionLogEventWithEffects[]\n fromValue: incremental.Value<EventMeta>\n fromRaw: Omit<SanityDocument, '_rev'>\n toValue: incremental.Value<EventMeta>\n toRaw: Omit<SanityDocument, '_rev'>\n}) {\n const fromInput = wrapValue<EventMeta>(fromValue, fromRaw, {\n fromValue(value) {\n return extractAnnotationForFromInput(transactions, value.endMeta)\n },\n fromMeta(meta) {\n return extractAnnotationForFromInput(transactions, meta)\n },\n })\n\n const toInput = wrapValue<EventMeta>(toValue, toRaw, {\n fromValue(value) {\n return extractAnnotationForToInput(transactions, value.startMeta)\n },\n fromMeta(meta) {\n return extractAnnotationForToInput(transactions, meta)\n },\n })\n return diffInput(fromInput, toInput)\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type Diff, diffInput} from '@sanity/diff'\nimport {type incremental} from 'mendoza'\n\nimport {type Annotation, type Chunk} from '../../../field/types'\nimport {wrapValue} from '../../events/diffValue'\nimport {type Timeline} from './Timeline'\n\n/**\n * @deprecated\n */\nexport type Meta = {chunk: Chunk; transactionIndex: number} | null\n\nfunction extractAnnotationForFromInput(\n timeline: Timeline,\n firstChunk: Chunk | null,\n meta: Meta,\n): Annotation {\n if (meta) {\n // The next transaction is where it disappeared:\n return annotationForTransactionIndex(timeline, meta.transactionIndex + 1, meta.chunk.index)\n } else if (firstChunk) {\n return annotationForTransactionIndex(timeline, firstChunk.start, firstChunk.index)\n }\n\n return null\n}\n\n// oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\nfunction extractAnnotationForToInput(timeline: Timeline, meta: Meta): Annotation {\n if (meta) {\n return annotationForTransactionIndex(timeline, meta.transactionIndex, meta.chunk.index)\n }\n\n return null\n}\n\n// oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\nfunction annotationForTransactionIndex(timeline: Timeline, idx: number, chunkIdx?: number) {\n const tx = timeline.transactionByIndex(idx)\n if (!tx) return null\n\n const chunk = timeline.chunkByTransactionIndex(idx, chunkIdx)\n if (!chunk) return null\n\n return {\n chunk,\n timestamp: tx.timestamp,\n author: tx.author,\n }\n}\n\n/**\n * @deprecated use the events api diff value with support for transactions instead.\n */\nexport function diffValue(\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n timeline: Timeline,\n firstChunk: Chunk | null,\n from: incremental.Value<Meta>,\n fromRaw: unknown,\n to: incremental.Value<Meta>,\n toRaw: unknown,\n): Diff<Annotation> {\n const fromInput = wrapValue<Meta>(from, fromRaw, {\n fromValue(value) {\n return extractAnnotationForFromInput(timeline, firstChunk, value.endMeta)\n },\n fromMeta(meta) {\n return extractAnnotationForFromInput(timeline, firstChunk, meta)\n },\n })\n\n const toInput = wrapValue<Meta>(to, toRaw, {\n fromValue(value) {\n return extractAnnotationForToInput(timeline, value.startMeta)\n },\n fromMeta(meta) {\n return extractAnnotationForToInput(timeline, meta)\n },\n })\n return diffInput(fromInput, toInput)\n}\n","export type Merger<T> = (left: T, right: T) => T | [T, T]\n\n/**\n * The two ended array supports pushing both at the beginning and\n * at the end while preserving indicies.\n */\nexport class TwoEndedArray<T extends {index: number}> {\n private _postive: T[] = []\n private _negative: T[] = []\n\n addToEnd(elem: T): void {\n elem.index = this._postive.length\n this._postive.push(elem)\n }\n\n addToBeginning(elem: T): void {\n // Prefer to place things at the positive side if possible.\n if (this.length == 0) {\n this.addToEnd(elem)\n return\n }\n\n elem.index = -(this._negative.length + 1)\n this._negative.push(elem)\n }\n\n mergeAtEnd(value: T, merger: Merger<T>): void {\n if (this.length === 0) {\n this.addToEnd(value)\n return\n }\n\n const idx = this.lastIdx\n const result = merger(this.get(idx), value)\n if (Array.isArray(result)) {\n this.set(idx, result[0])\n this.addToEnd(result[1])\n } else {\n this.set(idx, result)\n }\n }\n\n mergeAtBeginning(value: T, merger: Merger<T>): void {\n if (this.length === 0) {\n this.addToEnd(value)\n return\n }\n\n const idx = this.firstIdx\n const result = merger(value, this.get(idx))\n if (Array.isArray(result)) {\n this.set(idx, result[1])\n this.addToBeginning(result[0])\n } else {\n this.set(idx, result)\n }\n }\n\n removeFromEnd(): void {\n if (this._postive.length === 0) {\n this._negative.shift()\n } else {\n this._postive.pop()\n }\n }\n\n has(idx: number): boolean {\n if (idx >= 0) {\n return idx < this._postive.length\n }\n\n return -(idx + 1) < this._negative.length\n }\n\n get(idx: number): T {\n if (idx >= 0) {\n return this._postive[idx]\n }\n\n return this._negative[-(idx + 1)]\n }\n\n set(idx: number, value: T): void {\n if (idx >= 0) {\n value.index = idx\n this._postive[idx] = value\n } else {\n value.index = idx\n this._negative[-(idx + 1)] = value\n }\n }\n\n get lastIdx(): number {\n // Note: This also works correctly when _positive is empty (it returns -1)\n return this._postive.length - 1\n }\n\n get last(): T {\n return this.get(this.lastIdx)\n }\n\n get firstIdx(): number {\n // Note: This also works correctly when _negative is empty (it returns 0)\n return -this._negative.length\n }\n\n get first(): T {\n return this.get(this.firstIdx)\n }\n\n get length(): number {\n return this._postive.length + this._negative.length\n }\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type CombinedDocument} from './types'\n\nexport function getAttrs(doc: CombinedDocument): Record<string, unknown> | null {\n return doc.draft || doc.published\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type Diff} from '@sanity/diff'\nimport {type TransactionLogEventWithEffects} from '@sanity/types'\nimport {applyPatch, incremental} from 'mendoza'\n\nimport {type Annotation, type Chunk} from '../../../field/types'\nimport {chunkFromTransaction, mergeChunk} from './chunker'\nimport {diffValue, type Meta} from './diffValue'\nimport {type TraceEvent} from './replay'\nimport {TwoEndedArray} from './TwoEndedArray'\nimport {\n type CombinedDocument,\n type DocumentRemoteMutationVersionEvent,\n type Transaction,\n} from './types'\nimport {getAttrs} from './utils'\n\n/**\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta */\nexport type ParsedTimeRef = Chunk | 'loading' | 'invalid'\n\n/**\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta */\nexport interface TimelineOptions {\n publishedId: string\n enableTrace?: boolean\n}\n\n/**\n * Timeline maintains information about the history of a document:\n * Grouping raw translog entries into sensible groups, replaying and\n * reconstructing different versions and abstract other details.\n *\n * Note that this class by itself is not capable of _fetching_ information,\n * but will only organize and structure the incoming translog entries.\n *\n *\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta\n */\nexport class Timeline {\n reachedEarliestEntry = false\n\n publishedId: string\n draftId: string\n private _transactions = new TwoEndedArray<Transaction>()\n private _chunks = new TwoEndedArray<Chunk>()\n\n // These two properties are here to handle the case\n private _possiblePendingTransactions = new Map<\n string,\n {\n transaction: Transaction\n idx: number\n }\n >()\n private _recreateTransactionsFrom?: number\n private _trace?: TraceEvent[]\n\n constructor(opts: TimelineOptions) {\n this.publishedId = opts.publishedId\n this.draftId = `drafts.${opts.publishedId}`\n\n if (opts.enableTrace) {\n this._trace = []\n this._trace.push({\n type: 'initial',\n publishedId: opts.publishedId,\n })\n ;(window as any).__sanityTimelineTrace = this._trace\n }\n }\n\n get chunkCount(): number {\n return this._chunks.length\n }\n\n /** Maps over the chunk from newest to oldest. */\n mapChunks<T>(mapper: (chunk: Chunk, idx: number) => T): T[] {\n const result: T[] = []\n\n const firstIdx = this._chunks.firstIdx\n const lastIdx = this._chunks.lastIdx\n\n for (let idx = lastIdx; idx >= firstIdx; idx--) {\n result.push(mapper(this._chunks.get(idx), idx))\n }\n\n return result\n }\n\n reset(): void {\n this._transactions = new TwoEndedArray()\n this._chunks = new TwoEndedArray()\n this._possiblePendingTransactions = new Map()\n this._recreateTransactionsFrom = undefined\n this.reachedEarliestEntry = false\n }\n\n /**\n * Adds a remote mutation to the timeline. This methods assumes that the remote mutations\n * come in correct order for their respective version, but has no ordering requirements\n * across draft/published.\n *\n * Example: [D1, D2, P1] (where D1 and P1 were mutations done to the draft and published\n * version in the same transaction) is a valid input. [P1, D2, D1] is _not_ valid since\n * the mutation for the draft is out of order.\n */\n addRemoteMutation(entry: DocumentRemoteMutationVersionEvent): void {\n if (this._trace) this._trace.push({type: 'addRemoteMutation', event: entry})\n\n const pending = this._possiblePendingTransactions.get(entry.transactionId)\n\n const transaction: Transaction = pending\n ? pending.transaction\n : {\n index: 0,\n id: entry.transactionId,\n timestamp: entry.timestamp.toISOString(),\n author: entry.author,\n }\n\n if (entry.version === 'draft') {\n transaction.draftEffect = entry.effects as any\n } else {\n transaction.publishedEffect = entry.effects as any\n }\n\n if (pending) {\n this._possiblePendingTransactions.delete(entry.transactionId)\n this._invalidateTransactionFrom(pending.idx)\n } else {\n this._transactions.addToEnd(transaction)\n this._possiblePendingTransactions.set(entry.transactionId, {\n transaction,\n idx: this._transactions.lastIdx,\n })\n }\n }\n\n addTranslogEntry(event: TransactionLogEventWithEffects): void {\n if (this._trace) this._trace.push({type: 'addTranslogEntry', event})\n\n this._transactions.addToBeginning({\n index: 0,\n id: event.id,\n author: event.author,\n timestamp: event.timestamp,\n draftEffect: event.effects[this.draftId],\n publishedEffect: event.effects[this.publishedId],\n })\n }\n\n /** Mark that we've reached the earliest entry. */\n didReachEarliestEntry(): void {\n if (this._trace) this._trace.push({type: 'didReachEarliestEntry'})\n\n this.reachedEarliestEntry = true\n }\n\n /**\n * updateChunks synchronizes the chunks to match the current state\n * of the transactions array. After calling this method you need\n * to invalidate all Chunks.\n */\n updateChunks(): void {\n if (this._trace) this._trace.push({type: 'updateChunks'})\n\n this._removeInvalidatedChunks()\n this._addChunksFromTransactions()\n this._createInitialChunk()\n }\n\n private _removeInvalidatedChunks() {\n if (this._recreateTransactionsFrom) {\n while (this._chunks.length > 0) {\n const chunk = this._chunks.last\n if (this._recreateTransactionsFrom < chunk.end) {\n this._chunks.removeFromEnd()\n } else {\n break\n }\n }\n this._recreateTransactionsFrom = undefined\n }\n }\n\n private _addChunksFromTransactions() {\n const firstIdx = this._transactions.firstIdx\n const lastIdx = this._transactions.lastIdx\n\n // Add transactions at the end:\n const nextTransactionToChunk = this._chunks.length > 0 ? this._chunks.last.end : firstIdx\n for (let idx = nextTransactionToChunk; idx <= lastIdx; idx++) {\n const transaction = this._transactions.get(idx)\n this._chunks.mergeAtEnd(chunkFromTransaction(transaction), mergeChunk)\n }\n\n // Add transactions at the beginning:\n if (this._chunks.length == 0) return\n\n const firstTransactionChunked = this._chunks.first.start\n\n for (let idx = firstTransactionChunked - 1; idx >= firstIdx; idx--) {\n const transaction = this._transactions.get(idx)\n this._chunks.mergeAtBeginning(chunkFromTransaction(transaction), mergeChunk)\n }\n }\n\n private _invalidateTransactionFrom(idx: number) {\n if (this._recreateTransactionsFrom === undefined || idx < this._recreateTransactionsFrom) {\n this._recreateTransactionsFrom = idx\n }\n }\n\n private _createInitialChunk() {\n if (this.reachedEarliestEntry) {\n if (this._chunks.first?.type === 'initial') return\n\n const firstTx = this._transactions.first\n if (!firstTx) return\n const initialChunk = chunkFromTransaction(firstTx)\n initialChunk.type = 'initial'\n initialChunk.id = '@initial'\n initialChunk.end = initialChunk.start\n this._chunks.addToBeginning(initialChunk)\n }\n }\n\n /**\n * Resolves a time reference.\n *\n * Note that the chunk returned is only valid if the timeline stays constant.\n * Once the timeline is updated, you must re-parse all references.\n */\n parseTimeId(id: string): ParsedTimeRef {\n if (this._chunks.length === 0) {\n return this.reachedEarliestEntry ? 'invalid' : 'loading'\n }\n\n // NOTE:\n // This was refactored from\n // ```\n // const [timestampStr, chunkId] = id.split('/', 3)\n // ```\n // in order to avoid issues with `@microsoft/api-extractor`.\n const idSegments = id.split('/', 3)\n const timestampStr = idSegments.shift()\n const chunkId = idSegments.shift()\n const timestamp = Number(timestampStr)\n\n for (let idx = this._chunks.lastIdx; idx >= this._chunks.firstIdx; idx--) {\n const chunk = this._chunks.get(idx)\n if (chunk.id === chunkId) {\n return chunk\n }\n\n if (Date.parse(chunk.endTimestamp) + 60 * 60 * 1000 < timestamp) {\n // The chunk ended _before_ the timestamp we're asking for. This means that there\n // is no point in looking further and the chunk is invalid.\n\n // We add 1 hour to allow some slack since transactions are not guaranteed to be in order.\n return 'invalid'\n }\n }\n\n return this.reachedEarliestEntry ? 'invalid' : 'loading'\n }\n\n findLastPublishedBefore(chunk: Chunk | null): ParsedTimeRef {\n for (\n let chunkIdx = chunk ? chunk.index - 1 : this._chunks.lastIdx;\n chunkIdx >= this._chunks.firstIdx;\n chunkIdx--\n ) {\n const currentChunk = this._chunks.get(chunkIdx)\n if (currentChunk.type === 'publish' || currentChunk.type === 'initial') {\n return currentChunk\n }\n }\n\n if (!this.reachedEarliestEntry) return 'loading'\n\n return this._chunks.first\n }\n\n isLatestChunk(chunk: Chunk): boolean {\n return chunk === this._chunks.last\n }\n\n createTimeId(chunk: Chunk): string {\n return `${chunk.endTimestamp.valueOf()}/${chunk.id}`\n }\n\n lastChunk(): Chunk {\n return this._chunks.last\n }\n\n transactionByIndex(idx: number): Transaction | null {\n if (!this._transactions.has(idx)) return null\n return this._transactions.get(idx)\n }\n\n chunkByTransactionIndex(idx: number, startChunkIdx = 0): Chunk {\n let chunkIdx = startChunkIdx\n for (;;) {\n const chunk = this._chunks.get(chunkIdx)\n if (!chunk) throw new Error('transaction does not belong in any chunk')\n\n if (idx >= chunk.end) {\n chunkIdx++\n } else if (idx < chunk.start) {\n chunkIdx--\n } else {\n return chunk\n }\n }\n }\n\n replayBackwardsBetween(\n firstIdx: number,\n lastIdx: number,\n doc: CombinedDocument,\n ): CombinedDocument {\n let draft = doc.draft\n let published = doc.published\n\n for (let idx = lastIdx; idx >= firstIdx; idx--) {\n const transaction = this._transactions.get(idx)\n\n if (transaction.draftEffect) {\n draft = applyPatch(draft, transaction.draftEffect.revert)\n }\n\n if (transaction.publishedEffect) {\n published = applyPatch(published, transaction.publishedEffect.revert)\n }\n }\n\n return {draft, published}\n }\n\n replayBackwardsUntil(firstIdx: number, doc: CombinedDocument): CombinedDocument {\n return this.replayBackwardsBetween(firstIdx, this._transactions.lastIdx, doc)\n }\n\n calculateDiff(\n initialDoc: CombinedDocument,\n finalDoc: CombinedDocument,\n firstIdx: number,\n lastIdx: number,\n ): Diff<Annotation> {\n let draftValue = incremental.wrap<Meta>(initialDoc.draft, null)\n let publishedValue = incremental.wrap<Meta>(initialDoc.published, null)\n\n const initialValue = getValue(draftValue, publishedValue)\n const initialAttributes = getAttrs(initialDoc)\n let firstChunk: Chunk | null = null\n\n // Loop over all of the chunks:\n for (let chunkIdx = firstIdx; chunkIdx <= lastIdx; chunkIdx++) {\n const chunk = this._chunks.get(chunkIdx)\n if (!firstChunk) firstChunk = chunk\n\n for (let idx = chunk.start; idx < chunk.end; idx++) {\n const transaction = this._transactions.get(idx)\n\n const meta = {\n chunk,\n transactionIndex: idx,\n }\n\n const preDraftValue = draftValue\n const prePublishedValue = publishedValue\n\n if (transaction.draftEffect) {\n draftValue = incremental.applyPatch(draftValue, transaction.draftEffect.apply, meta)\n }\n\n if (transaction.publishedEffect) {\n publishedValue = incremental.applyPatch(\n publishedValue,\n transaction.publishedEffect.apply,\n meta,\n )\n }\n\n const didHaveDriaft = incremental.getType(preDraftValue) !== 'null'\n const haveDraft = incremental.getType(draftValue) !== 'null'\n const havePublished = incremental.getType(publishedValue) !== 'null'\n\n if (havePublished && !haveDraft) {\n publishedValue = incremental.rebaseValue(preDraftValue, publishedValue)\n }\n\n if (haveDraft && !didHaveDriaft) {\n draftValue = incremental.rebaseValue(prePublishedValue, draftValue)\n }\n }\n }\n\n const finalValue = incremental.getType(draftValue) === 'null' ? publishedValue : draftValue\n const finalAttributes = getAttrs(finalDoc)\n\n return diffValue(this, firstChunk, initialValue, initialAttributes, finalValue, finalAttributes)\n }\n}\n\nfunction getValue(draftValue: incremental.Value<Meta>, publishedValue: incremental.Value<Meta>) {\n return incremental.getType(draftValue) === 'null' ? publishedValue : draftValue\n}\n","import {ClientError, ServerError} from '@sanity/client'\nimport {\n type TransactionLogEventWithMutations,\n type TransactionLogEventWithEffects,\n} from '@sanity/types'\n\nimport {DEFAULT_STUDIO_CLIENT_HEADERS} from '../../studioClient'\n\ntype StreamResult =\n | (TransactionLogEventWithEffects & TransactionLogEventWithMutations)\n | {error: {description?: string; type: string}}\n\nexport async function getJsonStream(\n url: string,\n token: string | undefined,\n): Promise<ReadableStream<StreamResult>> {\n const options: RequestInit = token\n ? {headers: {...DEFAULT_STUDIO_CLIENT_HEADERS, Authorization: `Bearer ${token}`}}\n : {credentials: 'include', headers: DEFAULT_STUDIO_CLIENT_HEADERS}\n const response = await fetch(url, options)\n if (!response.ok) {\n throw await toHttpError(response, url)\n }\n return getStream(response)\n}\n\n/**\n * Builds the same error `@sanity/client` throws for a non-OK response, so callers (and the studio's\n * request-error handler, which only claims `HttpError`s) can treat translog failures like any other\n * API failure: `statusCode`, `response.headers` (e.g. `retry-after`) and the API's error message.\n */\nasync function toHttpError(response: Response, url: string): Promise<Error> {\n const text = await response.text()\n const headers = Object.fromEntries(response.headers.entries())\n let body: unknown = text\n if ((headers['content-type'] || '').includes('application/json')) {\n try {\n body = JSON.parse(text)\n } catch {\n // keep the raw text\n }\n }\n const res = {\n statusCode: response.status,\n statusMessage: response.statusText,\n headers,\n body,\n url,\n method: 'GET',\n }\n return response.status >= 500 ? new ServerError(res) : new ClientError(res)\n}\n\nfunction getStream(response: Response): ReadableStream<StreamResult> {\n const body = response.body\n if (!body) {\n throw new Error('Failed to read body from response')\n }\n\n let reader: ReadableStreamDefaultReader<Uint8Array>\n let cancelled = false\n\n return new ReadableStream<TransactionLogEventWithEffects & TransactionLogEventWithMutations>({\n start(controller): void | PromiseLike<void> {\n reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n\n reader\n .read()\n .then(function processResult(result): void | Promise<void> {\n if (result.done) {\n if (cancelled) {\n return\n }\n\n buffer = buffer.trim()\n if (buffer.length === 0) {\n controller.close()\n return\n }\n\n controller.enqueue(JSON.parse(buffer))\n controller.close()\n return\n }\n\n buffer += decoder.decode(result.value, {stream: true})\n const lines = buffer.split('\\n')\n\n for (let i = 0; i < lines.length - 1; ++i) {\n const line = lines[i].trim()\n if (line.length === 0) {\n continue\n }\n\n try {\n controller.enqueue(JSON.parse(line))\n } catch (err) {\n controller.error(err)\n cancelled = true\n void reader.cancel()\n return\n }\n }\n\n buffer = lines[lines.length - 1]\n\n return reader\n .read()\n .then(processResult)\n .catch((err) => controller.error(err))\n })\n .catch((err) => controller.error(err))\n },\n\n cancel(): void {\n cancelled = true\n void reader.cancel()\n },\n })\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type SanityDocument, type TransactionLogEventWithEffects} from '@sanity/types'\nimport {applyPatch} from 'mendoza'\n\nimport {type RemoteSnapshotVersionEvent} from '../../document/document-pair/checkoutPair'\nimport {type Timeline} from './Timeline'\nimport {type CombinedDocument, type DocumentRemoteMutationVersionEvent} from './types'\n\ntype VersionState = {\n id: string\n hasAttrs: boolean\n attrs: Record<string, unknown> | null\n rev: string | null\n events: Array<DocumentRemoteMutationVersionEvent>\n aligned: boolean\n}\n\nfunction emptyVersionState(id: string): VersionState {\n return {\n id,\n hasAttrs: false,\n attrs: null,\n rev: null,\n events: [],\n aligned: false,\n }\n}\n\nfunction align(history: TransactionLogEventWithEffects, state: VersionState): number {\n const idx = state.events.findIndex((evt) => history.id === evt.transactionId)\n if (idx >= 0) {\n // Return the next event as we don't want this to be included.\n return idx + 1\n }\n\n if (state.rev) {\n return state.rev === history.id ? 0 : -1\n }\n\n // At this point the document doesn't exist and we were not able to match\n // it up with a received mutation. This is a bit unfortunate as we don't\n // have a _reliably_ way of aligning it. For now we just always assume\n // that it's consistent.\n\n return 0\n}\n\nfunction startFromSnapshot(state: VersionState, doc: SanityDocument) {\n state.hasAttrs = true\n\n if (doc) {\n state.attrs = {...doc}\n if (typeof state.attrs._rev != 'string') throw new Error('snapshot has no _rev')\n state.rev = state.attrs._rev\n delete state.attrs._rev\n } else {\n state.attrs = null\n state.rev = null\n }\n\n state.events = []\n}\n\n/**\n * The timeline consists of data from (1) the history, (2) live draft mutations, and\n * (3) live published mutations. It's critical for us that the chain of transactions\n * is complete and without holes. The following class can be used as a layer in front\n * of Timeline to ensure this:\n *\n * - Invoke `appendRemoteSnapshotEvent` when there's an incoming remote mutation.\n * These mutations are buffered internally and _not_ passed to the timeline quite yet.\n *\n * - Once we've received snapshots for both draft and published, then `acceptsHistory`\n * becomes true and the caller can fetch a chunk of the translog. The flag\n * `earliestTransactionId` can be used to figure out where to fetch transactions from.\n *\n * - The caller invokes `prependHistoryEvent` for each of the events. These history events\n * are always pushed to the timeline and it will become available immediately.\n *\n * - Internally this class will then try to align the history event to the received\n * mutations and then dispatch to the timeline.\n *\n * - The aligner also maintains the latest revision for both the draft and the published version.\n *\n *\n */\nexport class Aligner {\n timeline: Timeline\n earliestTransactionId: string | null = null\n\n constructor(timeline: Timeline) {\n this.timeline = timeline\n this._states = {\n draft: emptyVersionState(timeline.draftId),\n published: emptyVersionState(timeline.publishedId),\n }\n }\n\n private _states: {\n draft: VersionState\n published: VersionState\n }\n\n appendRemoteSnapshotEvent(evt: RemoteSnapshotVersionEvent): void {\n if (evt.version === 'version') {\n return\n }\n\n const state = this._states[evt.version]\n\n if (evt.type === 'snapshot') {\n this._maybeInvalidateHistory()\n\n startFromSnapshot(state, evt.document)\n return\n }\n\n if (evt.type === 'remoteMutation') {\n if (state.aligned) {\n this._apply(state, evt)\n this.timeline.addRemoteMutation(evt)\n } else if (state.hasAttrs) {\n state.events.push(evt)\n } else {\n startFromSnapshot(state, evt.head)\n }\n }\n }\n\n prependHistoryEvent(evt: TransactionLogEventWithEffects): void {\n if (!this.acceptsHistory) throw new Error('cannot prepend history at this point')\n\n for (const state of Object.values(this._states)) {\n if (!state.aligned) {\n const idx = align(evt, state)\n\n if (idx >= 0) {\n this._alignAtIndex(state, idx)\n }\n }\n }\n\n this.timeline.addTranslogEntry(evt)\n this.earliestTransactionId = evt.id\n }\n\n didReachEarliestEntry(): void {\n for (const state of Object.values(this._states)) {\n if (!state.aligned) {\n if (state.attrs !== null) throw new Error('unable to find translog entry to align to')\n this._alignAtIndex(state, 0)\n }\n }\n this.timeline.didReachEarliestEntry()\n }\n\n get isAligned(): boolean {\n return Object.values(this._states).every((state) => state.aligned)\n }\n\n get acceptsHistory(): boolean {\n return this._isComplete\n }\n\n get currentDocument(): CombinedDocument {\n return {draft: this._states.draft.attrs, published: this._states.published.attrs}\n }\n\n private _alignAtIndex(state: VersionState, idx: number) {\n // These we must only apply locally since they are present in the fetched translog.\n for (const mutEvt of state.events.slice(0, idx)) {\n this._apply(state, mutEvt)\n }\n\n // ... while these must also be pushed to the timeline:\n for (const mutEvt of state.events.slice(idx)) {\n this._apply(state, mutEvt)\n this.timeline.addRemoteMutation(mutEvt)\n }\n\n state.events = []\n state.aligned = true\n }\n\n private get _isComplete(): boolean {\n return Object.values(this._states).every((state) => state.hasAttrs)\n }\n\n private _apply(state: VersionState, evt: DocumentRemoteMutationVersionEvent) {\n state.attrs = applyPatch(state.attrs, evt.effects.apply as any)\n state.rev = evt.transactionId\n }\n\n private _maybeInvalidateHistory() {\n if (this._isComplete) {\n for (const state of Object.values(this._states)) {\n state.aligned = false\n }\n this.earliestTransactionId = null\n this.timeline.reset()\n }\n }\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type Diff} from '@sanity/diff'\n\nimport {type Annotation, type Chunk} from '../../../field/types'\nimport {type Timeline} from './Timeline'\nimport {type CombinedDocument} from './types'\n\n/**\n * A reconstruction represents a single reconstruction of a\n */\nexport class Reconstruction {\n timeline: Timeline\n start: Chunk | null\n end: Chunk\n doc: CombinedDocument\n\n constructor(timeline: Timeline, doc: CombinedDocument, start: Chunk | null, end: Chunk) {\n this.timeline = timeline\n this.start = start\n this.end = end\n this.doc = doc\n }\n\n same(start: Chunk | null, end: Chunk): boolean {\n return this.start === start && this.end === end\n }\n\n private _startDocument?: CombinedDocument\n private _endDocument?: CombinedDocument\n private _diff?: Diff<Annotation>\n\n /** Returns the attributes as seen at the end of the range. */\n endAttributes(): Record<string, unknown> | null {\n return getAttrs(this.endDocument())\n }\n\n endDocument(): CombinedDocument {\n if (!this._endDocument) {\n this._endDocument = this.timeline.replayBackwardsUntil(this.end.end, this.doc)\n }\n\n return this._endDocument\n }\n\n /** Returns the attributes as seen at the end of the range. */\n startAttributes(): Record<string, unknown> | null {\n return getAttrs(this.startDocument())\n }\n\n startDocument(): CombinedDocument {\n if (!this.start) throw new Error('start required')\n\n if (!this._startDocument) {\n this._startDocument = this.timeline.replayBackwardsBetween(\n this.start.end,\n this.end.end - 1,\n this.endDocument(),\n )\n }\n\n return this._startDocument\n }\n\n diff(): Diff<Annotation> {\n if (!this._diff) {\n if (!this.start) throw new Error('start required')\n\n this._diff = this.timeline.calculateDiff(\n this.startDocument(),\n this.endDocument(),\n this.start.index + 1,\n this.end.index,\n )\n }\n\n return this._diff\n }\n}\n\nfunction getAttrs(doc: CombinedDocument) {\n return doc.draft || doc.published\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type SanityClient} from '@sanity/client'\nimport {type Diff, type ObjectDiff} from '@sanity/diff'\n\nimport {type Annotation, type Chunk} from '../../../field/types'\nimport {type RemoteSnapshotVersionEvent} from '../../document/document-pair/checkoutPair'\nimport {getJsonStream} from '../../events/getJsonStream'\nimport {Aligner} from './Aligner'\nimport {Reconstruction} from './Reconstruction'\nimport {type ParsedTimeRef, type Timeline} from './Timeline'\n\nconst TRANSLOG_ENTRY_LIMIT = 50\n\n/**\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta */\nexport type TimelineControllerOptions = {\n timeline: Timeline\n client: SanityClient\n documentId: string\n documentType: string\n handler?: (err: Error | null, controller: TimelineController) => void\n}\n\n/**\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta */\nexport type SelectionState = 'inactive' | 'rev' | 'range' | 'loading' | 'invalid'\n\n/**\n * The controller is responsible for fetching information\n * about a document and maintaining a Timeline.\n *\n *\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta\n */\nexport class TimelineController {\n timeline: Timeline\n client: SanityClient\n handler: TimelineControllerOptions['handler']\n\n version = 0\n\n /**\n * The selection state represents the different states of the current selection:\n * - inactive: No selection is active.\n * - rev: A selection is active for a single revision.\n * - range: A selection is active for a range and we have all the data needed to render it.\n * - loading: A selection is active, but we don't have the entries yet.\n * - invalid: The selection picked is invalid.\n */\n selectionState: SelectionState = 'inactive'\n\n constructor(options: TimelineControllerOptions) {\n this.timeline = options.timeline\n this.client = options.client\n this.handler = options.handler\n this._aligner = new Aligner(this.timeline)\n\n this.markChange()\n }\n\n private _aligner: Aligner\n\n private _fetchMore = false\n private _fetchAtLeast = 0\n private _isRunning = false\n private _isSuspended = false\n private _didErr = false\n\n private _since: string | null = null\n private _sinceTime: ParsedTimeRef | null = null\n private _rev: string | null = null\n private _revTime: ParsedTimeRef | null = null\n\n private _reconstruction?: Reconstruction\n\n setHandler(handler: TimelineControllerOptions['handler']): void {\n this.handler = handler\n }\n\n clearRange(): void {\n this.setRange(null, null)\n }\n\n setRange(since: string | null, rev: string | null): void {\n if (rev !== this._rev) this.setRevTime(rev)\n if (since !== this._since) this.setSinceTime(since)\n\n let _fetchAtLeast = 10\n\n if (this._sinceTime === 'loading' || this._revTime === 'loading' || !this._aligner.isAligned) {\n this.selectionState = 'loading'\n } else if (this._sinceTime === 'invalid' || this._revTime === 'invalid') {\n this.selectionState = 'invalid'\n } else if (this._sinceTime) {\n this.selectionState = 'range'\n\n const targetRev = this._revTime || this.timeline.lastChunk()\n\n if (this._sinceTime.index > targetRev.index) {\n this._revTime = 'invalid'\n this.selectionState = 'invalid'\n } else {\n this.setReconstruction(this._sinceTime, targetRev)\n }\n } else if (this._revTime) {\n this.selectionState = 'rev'\n this.setReconstruction(null, this._revTime)\n } else {\n this.selectionState = 'inactive'\n _fetchAtLeast = 0\n }\n\n this._fetchAtLeast = _fetchAtLeast\n\n this.start()\n }\n\n setLoadMore(flag: boolean): void {\n this._fetchMore = flag\n this.start()\n }\n\n get sinceTime(): Chunk | null {\n return this._sinceTime && typeof this._sinceTime === 'object' ? this._sinceTime : null\n }\n\n get revTime(): Chunk | null {\n return this._revTime && typeof this._revTime === 'object' ? this._revTime : null\n }\n\n get isLoading(): boolean {\n return this._isRunning\n }\n\n get realRevChunk(): Chunk {\n return this.revTime || this.timeline.lastChunk()\n }\n\n /** Returns true when there's an older revision we want to render. */\n onOlderRevision(): boolean {\n return Boolean(this._rev) && (this.selectionState === 'range' || this.selectionState === 'rev')\n }\n\n findRangeForNewRev(rev: Chunk): [string | null, string | null] {\n const revTimeId = this.timeline.isLatestChunk(rev) ? null : this.timeline.createTimeId(rev)\n\n if (!this._since) {\n return [null, revTimeId]\n }\n\n const sinceChunk = this.sinceTime\n if (sinceChunk && sinceChunk.index < rev.index) {\n return [this._since, revTimeId]\n }\n\n return ['@lastPublished', revTimeId]\n }\n\n findRangeForNewSince(since: Chunk): [string, string | null] {\n const revChunk = this.revTime\n\n // If the the `since` timestamp is earlier than the `rev`, then we can\n // accept it. Otherwise we'll move the current revision to the current draft.\n\n if (revChunk && since.index < revChunk.index) {\n return [this.timeline.createTimeId(since), this._rev]\n }\n\n return [this.timeline.createTimeId(since), null]\n }\n\n setRevTime(rev: string | null): void {\n this._rev = rev\n this._revTime = rev ? this.timeline.parseTimeId(rev) : null\n\n if (this._since === '@lastPublished') {\n // Make sure we invalidate it since this depends on the _rev.\n this._since = null\n this._sinceTime = null\n }\n }\n\n setSinceTime(since: string | null): void {\n if (since === '@lastPublished') {\n if (typeof this._revTime === 'string') {\n this._sinceTime = this._revTime\n } else {\n this._sinceTime = this.timeline.findLastPublishedBefore(this._revTime)\n }\n } else {\n this._sinceTime = since ? this.timeline.parseTimeId(since) : null\n }\n\n this._since = since\n }\n\n sinceAttributes(): Record<string, unknown> | null {\n return this._sinceTime && this._reconstruction ? this._reconstruction.startAttributes() : null\n }\n\n displayed(): Record<string, unknown> | null {\n return this._revTime && this._reconstruction ? this._reconstruction.endAttributes() : null\n }\n\n setReconstruction(since: Chunk | null, rev: Chunk): void {\n if (this._reconstruction && this._reconstruction.same(since, rev)) return\n this._reconstruction = new Reconstruction(\n this.timeline,\n this._aligner.currentDocument,\n since,\n rev,\n )\n }\n\n currentDiff(): Diff<Annotation> | null {\n return this._reconstruction ? this._reconstruction.diff() : null\n }\n\n currentObjectDiff(): ObjectDiff<Annotation> | null {\n const diff = this.currentDiff()\n if (diff) {\n if (diff.type === 'null') return null\n if (diff.type !== 'object') throw new Error(`ObjectDiff expected, got ${diff.type}`)\n }\n\n return diff as ObjectDiff<Annotation>\n }\n\n handleRemoteMutation(ev: RemoteSnapshotVersionEvent): void {\n this._aligner.appendRemoteSnapshotEvent(ev)\n this.markChange()\n\n // Make sure we fetch history as soon as possible.\n if (this._aligner.acceptsHistory) this.start()\n }\n\n start(): void {\n if (this._didErr) return\n\n if (!this._isRunning) {\n this._isRunning = true\n\n void this.tick().then(() => {\n this._isRunning = false\n })\n }\n }\n\n resume(): void {\n this._isSuspended = false\n }\n\n suspend(): void {\n this._isSuspended = true\n }\n\n private async tick() {\n const shouldFetchMore =\n this._aligner.acceptsHistory &&\n !this.timeline.reachedEarliestEntry &&\n (this.selectionState === 'loading' ||\n this._fetchMore ||\n this.timeline.chunkCount <= this._fetchAtLeast) &&\n !this._isSuspended\n\n if (!shouldFetchMore) {\n this._isRunning = false\n return\n }\n\n try {\n await this.fetchMoreTransactions()\n } catch (err) {\n this._didErr = true\n this.handler?.(err, this)\n return\n }\n\n await this.tick()\n }\n\n private async fetchMoreTransactions() {\n const publishedId = this.timeline.publishedId\n const draftId = this.timeline.draftId\n const clientConfig = this.client.config()\n const limit = TRANSLOG_ENTRY_LIMIT\n\n let queryParams = `tag=sanity.studio.structure.history&effectFormat=mendoza&excludeContent=true&excludeMutations=true&includeIdentifiedDocumentsOnly=true&reverse=true&limit=${limit}`\n let tid = this._aligner.earliestTransactionId\n if (tid) {\n queryParams += `&toTransaction=${tid}`\n }\n\n const transactionsUrl = this.client.getUrl(\n `/data/history/${clientConfig.dataset}/transactions/${publishedId},${draftId}?${queryParams}`,\n )\n const stream = await getJsonStream(transactionsUrl, clientConfig.token)\n const reader = stream.getReader()\n let count = 0\n\n for (;;) {\n // oxlint-disable-next-line no-await-in-loop\n const result = await reader.read()\n if (result.done) break\n\n if ('error' in result.value) {\n throw new Error(result.value.error.description || result.value.error.type)\n }\n\n count++\n\n if (result.value.id === tid) {\n // toTransaction is inclusive so we must ignore it when we fetch the next page\n continue\n }\n\n // For some reason, the aligner is now interested in a different set of entries.\n // This can happen if a new snapshot comes in as we're streaming the translog.\n // In this case it's safe to abort, and the run-loop will re-schedule it correctly.\n if (this._aligner.earliestTransactionId !== tid || !this._aligner.acceptsHistory) {\n return\n }\n\n this._aligner.prependHistoryEvent(result.value)\n tid = this._aligner.earliestTransactionId\n }\n\n // Same consistency checking here:\n if (this._aligner.earliestTransactionId !== tid || !this._aligner.acceptsHistory) {\n return\n }\n\n if (count < limit) {\n this._aligner.didReachEarliestEntry()\n }\n\n this.markChange()\n }\n\n private markChange() {\n this.timeline.updateChunks()\n\n this.setRevTime(this._rev)\n this.setSinceTime(this._rev)\n\n this.version++\n this.handler?.(null, this)\n }\n}\n","import {type Action, type SanityClient} from '@sanity/client'\nimport {type DocumentId, isDraftId, isVersionId} from '@sanity/id-utils'\nimport {\n isReference,\n type Reference,\n type SanityDocument,\n type TransactionLogEventWithMutations,\n} from '@sanity/types'\nimport {reduce as jsonReduce} from 'json-reduce'\nimport {from, type Observable} from 'rxjs'\nimport {map, mergeMap} from 'rxjs/operators'\n\nimport {isDev} from '../../environment'\nimport {getDraftId, getPublishedId, getVersionFromId, getIdPair} from '../../util/draftUtils'\nimport {isRecord} from '../../util/isRecord'\nimport {actionsApiClient} from '../document/document-pair/utils/actionsApiClient'\nimport {Timeline} from './history/Timeline'\nimport {TimelineController} from './history/TimelineController'\n\n/**\n * Represents a document revision identifier.\n * Can be either a specific revision string\n * or 'lastRevision' to get the most recent revision.\n *\n * @beta\n */\nexport type DocumentRevision = string | 'lastRevision'\n\n/**\n * @hidden\n * @beta */\nexport interface HistoryStore {\n getDocumentAtRevision: (\n documentId: string,\n revision: DocumentRevision,\n ) => Promise<SanityDocument | undefined>\n\n getHistory: (\n documentIds: string[],\n options?: {time?: string; revision?: string},\n ) => Promise<{documents: SanityDocument[]}>\n\n getTransactions: (documentIds: string[]) => Promise<TransactionLogEventWithMutations[]>\n\n restore: (\n id: string,\n targetId: string,\n rev: DocumentRevision,\n options?: RestoreOptions,\n ) => Observable<void>\n\n /**\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @internal\n */\n getTimelineController: (options: {\n client: SanityClient\n documentId: string\n documentType: string\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n }) => TimelineController\n}\n\ninterface RestoreOptions {\n fromDeleted: boolean\n useServerDocumentActions?: boolean\n}\n\nconst documentRevisionCache: Record<string, Promise<SanityDocument | undefined> | undefined> =\n Object.create(null)\n\nconst getHistory = (\n client: SanityClient,\n documentIds: string[],\n options: {time?: string; revision?: string} = {},\n): Promise<{documents: SanityDocument[]}> => {\n const ids = Array.isArray(documentIds) ? documentIds : [documentIds]\n const {time, revision} = options\n\n if (time && revision) {\n throw new Error(`getHistory can't handle both time and revision parameters`)\n }\n\n const dataset = client.config().dataset\n let url = `/data/history/${dataset}/documents/${ids.join(',')}`\n\n if (revision) {\n url = `${url}?revision=${revision}`\n } else {\n const timestamp = time || new Date().toISOString()\n\n url = `${url}?time=${timestamp}`\n }\n\n return client.request({url})\n}\n\nconst getDocumentAtRevision = (\n client: SanityClient,\n documentId: string,\n revision: DocumentRevision,\n): Promise<SanityDocument | undefined> => {\n const publishedId = getPublishedId(documentId)\n const draftId = getDraftId(documentId)\n const versionId = isVersionId(documentId as DocumentId) ? documentId : undefined\n const idsToQuery = [publishedId, draftId, versionId].filter(Boolean) as DocumentId[]\n\n const isLastRevision = revision === 'lastRevision'\n\n if (!isLastRevision) {\n const cacheKey = `${documentId}@${revision}`\n const cached = documentRevisionCache[cacheKey]\n if (cached) {\n return cached\n }\n }\n\n const dataset = client.config().dataset\n const url = `/data/history/${dataset}/documents/${idsToQuery.join(',')}?${\n isLastRevision ? 'lastRevision=true' : `revision=${revision}`\n }`\n\n const entry = client\n .request<{documents?: SanityDocument[]}>({url, tag: 'history-revision'})\n .then((result) => {\n const documents = result.documents || []\n const published = documents.find((res) => res._id === publishedId)\n const draft = documents.find((res) => res._id === draftId)\n const version = versionId ? documents.find((res) => res._id === versionId) : undefined\n\n if (revision !== 'lastRevision') {\n if (version?._rev === revision) return version\n if (draft?._rev === revision) return draft\n if (published?._rev === revision) return published\n return undefined\n }\n return version || draft || published\n })\n\n if (!isLastRevision) {\n const cacheKey = `${documentId}@${revision}`\n documentRevisionCache[cacheKey] = entry\n }\n\n return entry\n}\n\nconst getTimelineController = ({\n client,\n documentId,\n documentType,\n}: {\n client: SanityClient\n documentId: string\n documentType: string\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n}): TimelineController => {\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n const timeline = new Timeline({\n enableTrace: isDev,\n publishedId: documentId,\n })\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n return new TimelineController({\n client,\n documentId,\n documentType,\n timeline,\n })\n}\n\nconst getTransactions = async (\n client: SanityClient,\n documentIds: string | string[],\n): Promise<TransactionLogEventWithMutations[]> => {\n const ids = Array.isArray(documentIds) ? documentIds : [documentIds]\n const dataset = client.config().dataset\n const query = {excludeContent: 'true', includeIdentifiedDocumentsOnly: 'true'}\n const url = `/data/history/${dataset}/transactions/${ids.join(',')}`\n const result = await client.request({url, query})\n const transactions = result\n .toString('utf8')\n .split('\\n')\n .filter(Boolean)\n .map((line: string) => JSON.parse(line))\n\n return transactions\n}\n\nconst getAllRefIds = (doc: SanityDocument): string[] =>\n jsonReduce(\n doc as any,\n (acc: any, node) => (isReference(node) && !acc.includes(node._ref) ? [...acc, node._ref] : acc),\n [],\n )\n\nfunction jsonMap(value: unknown, mapFn: any): any {\n if (Array.isArray(value)) {\n return mapFn(\n value.map((item) => jsonMap(item, mapFn)).filter((item) => typeof item !== 'undefined'),\n )\n }\n\n if (isRecord(value)) {\n return mapFn(\n Object.keys(value).reduce<Record<string, unknown>>((res, key) => {\n const mappedValue = jsonMap(value[key], mapFn)\n if (typeof mappedValue !== 'undefined') {\n res[key] = mappedValue\n }\n\n return res\n }, {}),\n )\n }\n\n return mapFn(value)\n}\n\nconst mapRefNodes = (doc: SanityDocument, mapFn: (node: Reference) => Reference | undefined) =>\n jsonMap(doc, (node: unknown) => (isReference(node) ? mapFn(node) : node))\n\n/** @internal */\nexport const removeMissingReferences = (\n doc: SanityDocument,\n existingIds: Record<string, boolean | undefined>,\n): SanityDocument =>\n mapRefNodes(doc, (refNode) => {\n const documentExists = existingIds[refNode._ref]\n return documentExists ? refNode : undefined\n })\n\nfunction restore(\n client: SanityClient,\n documentId: string,\n targetDocumentId: string,\n rev: DocumentRevision,\n options?: RestoreOptions,\n): Observable<void> {\n return from(getDocumentAtRevision(client, targetDocumentId, rev)).pipe(\n mergeMap((documentAtRevision) => {\n if (!documentAtRevision) {\n throw new Error(`Unable to find document with ID ${documentId} at revision ${rev}`)\n }\n if (rev !== 'lastRevision' && documentAtRevision?._rev !== rev) {\n throw new Error(\n `Restored revision ${documentAtRevision?._rev} does not match expected revision ${rev}`,\n )\n }\n\n const existingIdsQuery = getAllRefIds(documentAtRevision)\n .map((refId) => `\"${refId}\": defined(*[_id==\"${refId}\"]._id)`)\n .join(',')\n\n return client.observable\n .fetch<Record<string, boolean | undefined>>(`{${existingIdsQuery}}`)\n .pipe(map((existingIds) => removeMissingReferences(documentAtRevision, existingIds)))\n }),\n map((documentAtRevision) => {\n // Remove _updatedAt\n const {_updatedAt, ...document} = documentAtRevision\n return {...document, _id: targetDocumentId}\n }),\n mergeMap((restoredDraft) => {\n // `sanity.action.document.replaceDraft` requires `attributes._id` to be\n // prefixed with either `drafts.` or `versions.<bundleId>`. When it isn't\n // (e.g. restoring a live-edit document directly onto the published id),\n // fall back to the mutation API, matching the non-server-actions path.\n const canUseServerAction =\n isDraftId(targetDocumentId as DocumentId) || isVersionId(targetDocumentId as DocumentId)\n\n if (options?.useServerDocumentActions && canUseServerAction) {\n const replaceDraftAction: Action = {\n actionType: 'sanity.action.document.replaceDraft',\n publishedId: documentId,\n attributes: restoredDraft,\n }\n return actionsApiClient(\n client,\n // The pair derives from the *target* id: `documentId` is always the published group id\n // (its bundle segment is always undefined), while the target may be a version document\n // (release or variant scoped) whose actions require the versioned API client.\n getIdPair(documentId, {version: getVersionFromId(targetDocumentId)}),\n ).observable.action(\n options.fromDeleted\n ? [\n {\n actionType: 'sanity.action.document.create',\n publishedId: documentId,\n attributes: restoredDraft,\n // This will guard against a race where someone else restores a deleted document at the same time\n ifExists: 'fail',\n },\n replaceDraftAction,\n ]\n : replaceDraftAction,\n )\n }\n\n return client.observable.createOrReplace(restoredDraft, {visibility: 'async'})\n }),\n map(() => undefined),\n )\n}\n\n/** @internal */\nexport interface HistoryStoreOptions {\n client: SanityClient\n}\n\n/** @internal */\nexport function createHistoryStore({client}: HistoryStoreOptions): HistoryStore {\n return {\n getDocumentAtRevision: (documentId, revision) =>\n getDocumentAtRevision(client, documentId, revision),\n\n getHistory: (documentIds, options) => getHistory(client, documentIds, options),\n\n getTransactions: (documentIds) => getTransactions(client, documentIds),\n\n restore: (id, targetId, rev, options) => restore(client, id, targetId, rev, options),\n\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n getTimelineController,\n }\n}\n","/**\n * Whether or not the current environment supports localStorage.\n * Checks that values can actually be set/removed, to trigger any privacy settings.\n *\n * @internal\n */\nexport const supportsLocalStorage = (() => {\n // Non-browser runtimes (Node.js 22+, Bun, Deno) may expose a built-in\n // `localStorage` global that either warns or behaves differently from the\n // browser implementation. Since this utility is only useful in real browsers,\n // bail out in non-browser environments — even if browser globals have been\n // mocked (e.g., jsdom in CLI commands/tests). `process.versions` is set by\n // all major server-side runtimes and is not faked by jsdom.\n // Note that `process.versions` may also be defined by frameworks.\n // E.g. Next.js/Turbopack polyfills it and sets it to an empty object\n if (\n typeof process !== 'undefined' &&\n typeof process.versions !== 'undefined' &&\n typeof process.versions.node !== 'undefined'\n ) {\n return false\n }\n\n const key = '__tmp_supports_local_storage'\n\n try {\n if (typeof localStorage === 'undefined') {\n return false\n }\n\n localStorage.setItem(key, '---')\n localStorage.removeItem(key)\n return true\n } catch {\n return false\n }\n})()\n","import {type KeyValueStoreValue} from '../types'\n\nexport function createMemoryStorage() {\n const DB = Object.create(null)\n return {\n getKey(key: string): KeyValueStoreValue | null {\n return DB[key] || null\n },\n setKey(key: string, value: KeyValueStoreValue) {\n DB[key] = value\n },\n }\n}\n","import {supportsLocalStorage} from '../../../util/supportsLocalStorage'\nimport {type KeyValueStoreValue} from '../types'\nimport {createMemoryStorage} from './memoryStorage'\n\nfunction tryParse(val: string) {\n try {\n return JSON.parse(val)\n } catch (err) {\n console.warn(`Failed to parse settings: ${err.message}`)\n return null\n }\n}\n\nfunction createLocalStoreStorage() {\n if (!supportsLocalStorage) {\n return createMemoryStorage()\n }\n\n function getKey(key: string): KeyValueStoreValue | null {\n const val = localStorage.getItem(key)\n\n return val === null ? null : tryParse(val)\n }\n\n const setKey = function (key: string, nextValue: KeyValueStoreValue) {\n // Can't stringify undefined, and nulls are what\n // `getItem` returns when key does not exist\n if (typeof nextValue === 'undefined' || nextValue === null) {\n localStorage.removeItem(key)\n } else {\n localStorage.setItem(key, JSON.stringify(nextValue))\n }\n }\n return {getKey, setKey}\n}\n\nexport const localStoreStorage = createLocalStoreStorage()\n","import {dequal as isEqual} from 'dequal/lite'\nimport {merge, of} from 'rxjs'\nimport {distinctUntilChanged, tap} from 'rxjs/operators'\n\nimport {localStoreStorage} from './storage/localStoreStorage'\nimport {type KeyValueStore, type KeyValueStoreValue} from './types'\n\n/**\n * Wraps a KeyValueStore and adds Stale-While-Revalidate (SWR) behavior to it\n */\nexport function withLocalStorageSWR(wrappedStore: KeyValueStore): KeyValueStore {\n function getKey(key: string) {\n return merge(\n of(localStoreStorage.getKey(key)),\n wrappedStore.getKey(key).pipe(\n tap((wrappedStoreValue) => {\n localStoreStorage.setKey(key, wrappedStoreValue)\n }),\n ),\n ).pipe(distinctUntilChanged(isEqual))\n }\n function setKey(key: string, nextValue: KeyValueStoreValue) {\n localStoreStorage.setKey(key, nextValue)\n return wrappedStore.setKey(key, nextValue)\n }\n return {\n getKey,\n setKey,\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport DataLoader from 'dataloader'\n\nimport {DEFAULT_STUDIO_CLIENT_OPTIONS} from '../../../studioClient'\nimport {type KeyValueStoreValue} from '../types'\nimport {type KeyValuePair} from './types'\n\n/** @internal */\nexport interface ServerStorageOptions {\n client: SanityClient\n}\n\nexport interface ServerStorage {\n getKey: (key: string) => Promise<KeyValueStoreValue | null>\n setKey: (key: string, nextValue: unknown) => Promise<KeyValueStoreValue>\n}\n\n/**\n * Backend uses the Sanity client to store and retrieve key-value pairs from the /users/me/keyvalue endpoint.\n * @internal\n */\nexport function createServerStorage({client: _client}: ServerStorageOptions): ServerStorage {\n const client = _client.withConfig(DEFAULT_STUDIO_CLIENT_OPTIONS)\n\n const keyValueLoader = new DataLoader<string, KeyValueStoreValue | null>(async (keys) => {\n const value = await client\n .request<KeyValuePair[]>({\n url: `/users/me/keyvalue/${keys.join(',')}`,\n })\n .catch((error) => {\n console.error('Error fetching data:', error)\n return Array(keys.length).fill(null)\n })\n\n // there are instances where the valeu might be null\n const keyValuePairs = (value || []).reduce(\n (acc, next) => {\n if (next?.key) {\n acc[next.key] = next.value\n }\n return acc\n },\n {} as Record<string, KeyValueStoreValue | null>,\n )\n\n return keys.map((key) => keyValuePairs[key] || null)\n })\n\n const getKey = (key: string) => {\n return keyValueLoader.load(key)\n }\n\n const setKey = (key: string, nextValue: unknown) => {\n return client\n .request<KeyValuePair[]>({\n method: 'PUT',\n url: `/users/me/keyvalue`,\n body: [{key, value: nextValue}],\n })\n .then(\n (response) => {\n const pair = response[0]\n keyValueLoader.clear(pair.key)\n keyValueLoader.prime(pair.key, pair.value)\n return pair.value\n },\n (error) => {\n console.error('Error setting data:', error)\n return null\n },\n )\n }\n\n return {\n getKey,\n setKey,\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {dequal as isEqual} from 'dequal/lite'\nimport {concat, type Observable, Subject} from 'rxjs'\nimport {distinctUntilChanged, filter, map} from 'rxjs/operators'\n\nimport {createServerStorage} from './storage/serverStorage'\nimport {type KeyValueStore, type KeyValueStoreValue} from './types'\n\nexport function createServerKeyValueStore({client}: {client: SanityClient}): KeyValueStore {\n const serverStorage = createServerStorage({client})\n\n const events$ = new Subject<{\n type: 'optimistic' | 'commit'\n key: string\n value: KeyValueStoreValue\n }>()\n\n function getKey(key: string) {\n return serverStorage.getKey(key)\n }\n\n function setKey(key: string, value: KeyValueStoreValue) {\n events$.next({type: 'optimistic', key, value})\n\n /*\n * The backend returns the result of the set operation, so we can just pass that along.\n * Most utils do not use it (they will take advantage of local state first) but it reflects the\n * backend function and could be useful for debugging.\n */\n return serverStorage.setKey(key, value).then((storedValue) => {\n events$.next({type: 'commit', key, value: storedValue})\n return storedValue\n })\n }\n\n return {\n getKey(key: string): Observable<KeyValueStoreValue | null> {\n return concat(\n getKey(key),\n events$.pipe(\n filter((event) => event.key === key),\n map((event) => event.value),\n distinctUntilChanged(isEqual),\n ),\n )\n },\n setKey,\n }\n}\n","import {type SanityClient} from '@sanity/client'\n\nimport {withLocalStorageSWR} from './localStorageSWR'\nimport {createServerKeyValueStore} from './serverKeyValueStore'\n\n/** @internal */\nexport function createKeyValueStore(options: {client: SanityClient}) {\n return withLocalStorageSWR(createServerKeyValueStore(options))\n}\n","import {type BifurClient} from '@sanity/bifur-client'\nimport {EMPTY, type Observable} from 'rxjs'\nimport {map, share} from 'rxjs/operators'\n\nimport {type PresenceLocation} from '../types'\nimport {type Transport, type TransportEvent, type TransportMessage} from './transport'\n\ntype BifurStateMessage = {\n type: 'state'\n i: string\n m: {\n sessionId: string\n locations: PresenceLocation[]\n }\n}\n\ntype BifurDisconnectMessage = {\n type: 'disconnect'\n i: string\n m: {session: string}\n}\n\ntype RollCallEvent = {\n type: 'rollCall'\n i: string\n session: string\n}\n\ntype IncomingBifurEvent<T> = RollCallEvent | BifurStateMessage | BifurDisconnectMessage\n\nconst handleIncomingMessage = (event: IncomingBifurEvent<Location[]>): TransportEvent => {\n if (event.type === 'rollCall') {\n return {\n type: 'rollCall',\n userId: event.i,\n sessionId: event.session,\n }\n }\n if (event.type === 'state') {\n const {sessionId, locations} = event.m\n return {\n type: 'state',\n userId: event.i,\n sessionId: sessionId,\n timestamp: new Date().toISOString(),\n locations,\n }\n }\n\n if (event.type === 'disconnect') {\n return {\n type: 'disconnect',\n userId: event.i,\n sessionId: event.m.session,\n timestamp: new Date().toISOString(),\n }\n }\n\n throw new Error(`Got unknown presence event: ${JSON.stringify(event)}`)\n}\n\nexport const createBifurTransport = (bifur: BifurClient, sessionId: string): Transport => {\n const incomingEvents$: Observable<TransportEvent> = bifur\n .listen<IncomingBifurEvent<Location[]>>('presence')\n .pipe(map(handleIncomingMessage))\n\n const dispatchMessage = (message: TransportMessage): Observable<undefined> => {\n if (message.type === 'rollCall') {\n return bifur.request('presence_rollcall', {session: sessionId})\n }\n\n if (message.type === 'state') {\n return bifur.request('presence_announce', {\n data: {locations: message.locations, sessionId},\n })\n }\n\n if (message.type === 'disconnect') {\n return bifur.request('presence_disconnect', {session: sessionId})\n }\n\n return EMPTY\n }\n\n return [incomingEvents$.pipe(share()), dispatchMessage]\n}\n","import sample from 'lodash-es/sample.js'\nimport {defer, timer} from 'rxjs'\nimport {map, mergeMapTo, shareReplay} from 'rxjs/operators'\n\nimport {type StateEvent} from './message-transports/transport'\n\nconst USERIDS = [\n 'pqSMwf6hH',\n 'pnLYqNfv5',\n 'priDVVmy8',\n 'p0NFOU0j8',\n 'pTDl2jw8d',\n 'pHMeQnTse',\n 'pDQYzJbyS',\n 'pZyoPHKUs',\n 'p4Tyi2Be5',\n 'pb9vii060',\n 'pE8yhOisw',\n 'p7Fd2C6Cj',\n 'p3exSgYCx',\n 'pbIQRYViC',\n 'p8GJaTEhN',\n 'p27ewL8aM',\n 'pYg97z75S',\n 'pdLr4quHv',\n 'pkJXiDgg6',\n 'pkl4UAKcA',\n\n // Included to ensure we handle the case when a user profile cannot\n // be fetched due to insufficient privileges or similar\n 'pNoExists',\n]\n\nconst PATHS = [\n ['nested', 'first'],\n ['nested', 'second'],\n [\n 'nestedArray',\n {_key: '565c867c8dac'},\n 'arrayNo1',\n {_key: 'a645548a8f01'},\n 'arrayNo1',\n {_key: '1685e372c40f'},\n 'fieldNo0',\n ],\n ['nestedArray', {_key: '565c867c8dac'}, 'fieldNo0'],\n ['nestedArray', {_key: '565c867c8dac'}, 'arrayNo19', {_key: 'a02e7a93e2a2'}, 'fieldNo0'],\n ['nestedArray', {_key: '565c867c8dac'}, 'arrayNo19', {_key: 'a02e7a93e2a2'}, 'fieldNo19'],\n ['address', 'country'],\n ['address', 'street'],\n ['customInputWithDefaultPresence', 'row3', 'cell3'],\n]\n\nexport const mock$ = defer(() => timer(0, 10000)).pipe(\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n mergeMapTo(USERIDS),\n map((id, n): StateEvent => ({\n type: 'state',\n userId: id,\n sessionId: id + n,\n timestamp: new Date().toISOString(),\n locations: [\n {\n type: 'document',\n documentId: 'presence-debug',\n lastActiveAt: new Date().toISOString(),\n path: sample(PATHS),\n },\n ] as any,\n })),\n shareReplay(),\n)\n","import {type BifurClient} from '@sanity/bifur-client'\nimport {type User} from '@sanity/types'\nimport {dequal as isEqual} from 'dequal/lite'\nimport flatten from 'lodash-es/flatten.js'\nimport groupBy from 'lodash-es/groupBy.js'\nimport omit from 'lodash-es/omit.js'\nimport uniq from 'lodash-es/uniq.js'\nimport {nanoid} from 'nanoid'\nimport {\n BehaviorSubject,\n combineLatest,\n defer,\n EMPTY,\n from,\n fromEvent,\n merge,\n NEVER,\n type Observable,\n timer,\n} from 'rxjs'\nimport {\n auditTime,\n distinctUntilChanged,\n filter,\n map,\n mergeMapTo,\n scan,\n share,\n shareReplay,\n switchMap,\n switchMapTo,\n takeUntil,\n tap,\n withLatestFrom,\n} from 'rxjs/operators'\n\nimport {documentIdEquals} from '../../util/draftUtils'\nimport {type ConnectionStatusStore} from '../connection-status/connection-status-store'\nimport {debugParams$} from '../debugParams/debugParams'\nimport {type UserStore} from '../user/userStore'\nimport {createBifurTransport} from './message-transports/bifurTransport'\nimport {\n type DisconnectEvent,\n type RollCallEvent,\n type StateEvent,\n type TransportEvent,\n} from './message-transports/transport'\nimport {mock$} from './mock-events'\nimport {\n type DocumentPresence,\n type GlobalPresence,\n type PresenceLocation,\n type Session,\n type UserSessionPair,\n} from './types'\n\n/**\n * @hidden\n * @beta */\nexport interface PresenceStore {\n /**\n * @internal\n */\n documentPresence: (\n documentId: string,\n options?: {excludeVersions?: boolean},\n ) => Observable<DocumentPresence[]>\n\n /**\n * @internal\n */\n globalPresence$: Observable<GlobalPresence[]>\n\n /**\n * @internal\n */\n reportLocations: (locations: PresenceLocation[]) => Observable<void>\n\n /**\n * @internal\n */\n setLocation: (nextLocation: PresenceLocation[]) => void\n\n /**\n * @internal\n */\n debugPresenceParam$: Observable<string[]>\n}\n\nconst KEY = 'presence_session_id'\nconst generate = () => nanoid(16)\n\n// We're keeping the session id in sessionStorage as it will survive page reloads.\n// todo:\n// There's a potential issue with window.open(...) here as it inherits the top level session storage and thus will\n// re-use session ids:\n// > Opening a page in a new tab or window creates a new session with the value of the top-level browsing context,\n// which differs from how session cookies work.\n// More at https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage\n// This is _probably_ a quite marginal case and not going to be much of a issue in practice\nfunction getSessionId() {\n try {\n return window.sessionStorage.getItem(KEY)\n } catch {\n // We don't want to fail hard if session storage can't be accessed for some reason\n }\n return null\n}\n\nfunction setSessionId(id: string) {\n try {\n window.sessionStorage.setItem(KEY, id)\n } catch {\n // We don't want to fail hard if session storage can't be accessed for some reason\n }\n return id\n}\n\n/** @internal */\nexport const SESSION_ID = getSessionId() || setSessionId(generate())\n\n/** @internal */\nexport function createPresenceStore(context: {\n bifur: BifurClient\n connectionStatusStore: ConnectionStatusStore\n userStore: UserStore\n}): PresenceStore {\n const {bifur, connectionStatusStore, userStore} = context\n\n const [presenceEvents$, sendMessage] = createBifurTransport(bifur, SESSION_ID)\n\n const currentLocation$ = new BehaviorSubject<PresenceLocation[]>([])\n const locationChange$ = currentLocation$.pipe(distinctUntilChanged())\n\n // export\n const setLocation = (nextLocation: PresenceLocation[]) => {\n currentLocation$.next(nextLocation)\n }\n\n // export\n const reportLocations = (locations: PresenceLocation[]) =>\n sendMessage({type: 'state', locations: locations})\n\n const requestRollCall = () => sendMessage({type: 'rollCall'})\n\n const rollCallRequests$ = presenceEvents$.pipe(\n filter((event: TransportEvent): event is RollCallEvent => event.type === 'rollCall'),\n // do not respond to my own rollcall requests\n filter((event: RollCallEvent) => event.sessionId !== SESSION_ID),\n )\n\n const REPORT_MIN_INTERVAL = 30000\n\n // Interval to report my own location at\n const reportLocationInterval$ = timer(0, REPORT_MIN_INTERVAL)\n\n const reportLocation$ = defer(() => merge(locationChange$, rollCallRequests$)).pipe(\n switchMap(() => reportLocationInterval$),\n withLatestFrom(currentLocation$),\n map(([, locations]) => locations),\n auditTime(200),\n switchMap((locations) => reportLocations(locations)),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n mergeMapTo(EMPTY),\n share(),\n )\n\n // This represents my rollcall request to other clients\n // Note: We are requesting a rollcall whenever we (re)connect\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const myRollCall$ = defer(() => requestRollCall()).pipe(mergeMapTo(EMPTY))\n\n const connectionChange$ = connectionStatusStore.connectionStatus$.pipe(\n map((status) => status.type),\n filter((statusType) => statusType === 'connected' || statusType === 'error'),\n distinctUntilChanged(),\n )\n\n // export\n const debugPresenceParam$ = debugParams$.pipe(\n map((args) => args.find((arg) => arg.startsWith('presence='))),\n map(\n (arg) =>\n arg\n ?.split('presence=')[1]\n .split(',')\n .map((r) => r.trim()) || [],\n ),\n )\n\n const useMock$ = debugPresenceParam$.pipe(\n filter((args) => args.includes('fake_others')),\n tap(() => {\n // oxlint-disable-next-line no-console\n console.log(\n 'Faking other users present in the studio. They will hang out in the document with _type: \"presence\" and _id: \"presence-debug\"',\n )\n }),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n switchMapTo(mock$),\n )\n\n const debugIntrospect$ = debugPresenceParam$.pipe(map((args) => args.includes('show_own')))\n\n const syncEvent$ = merge(myRollCall$, presenceEvents$).pipe(\n filter(\n (event: TransportEvent): event is StateEvent | DisconnectEvent =>\n event.type === 'state' || event.type === 'disconnect',\n ),\n )\n\n const stateEventToSession = (stateEvent: StateEvent): Session => {\n return {\n lastActiveAt: stateEvent.timestamp,\n locations: stateEvent.locations,\n sessionId: stateEvent.sessionId,\n userId: stateEvent.userId,\n }\n }\n\n const states$: Observable<{[sessionId: string]: Session}> = merge(syncEvent$, useMock$).pipe(\n scan(\n (keyed, event: StateEvent | DisconnectEvent): {[sessionId: string]: Session} =>\n event.type === 'disconnect'\n ? omit(keyed, event.sessionId)\n : {...keyed, [event.sessionId]: stateEventToSession(event)},\n {},\n ),\n )\n\n const allSessions$: Observable<UserSessionPair[]> = connectionChange$.pipe(\n switchMap((status) => (status === 'connected' ? merge(states$, reportLocation$) : NEVER)),\n map((keyedSessions) => Object.values(keyedSessions)),\n switchMap((sessions) => {\n const userIds = uniq(sessions.map((sess) => sess.userId))\n return from(userStore.getUsers(userIds)).pipe(\n map((users) =>\n sessions\n .map((session) => ({\n user: users.find((res) => res.id === session.userId),\n session: session,\n }))\n // If we failed to find a user profile for a session, remove it\n .filter(userSessionPairHasUser),\n ),\n )\n }),\n takeUntil(\n fromEvent(window, 'beforeunload').pipe(switchMap(() => sendMessage({type: 'disconnect'}))),\n ),\n shareReplay({refCount: true, bufferSize: 1}),\n )\n\n function userSessionPairHasUser(pair: Partial<UserSessionPair>): pair is UserSessionPair {\n return Boolean(pair.user && pair.session)\n }\n\n // export\n const globalPresence$: Observable<GlobalPresence[]> = allSessions$.pipe(\n map((sessions): {user: User; sessions: Session[]}[] => {\n const grouped = groupBy(\n sessions.map((s) => s.session),\n (e) => e.userId,\n )\n\n return Object.keys(grouped).map((userId): {user: User; sessions: Session[]} => ({\n user: sessions.find((s) => s.user.id === userId)?.user as User,\n sessions: grouped[userId],\n }))\n }),\n withLatestFrom(debugIntrospect$),\n map(([userAndSessions, debugIntrospect]) =>\n userAndSessions.filter(\n (userAndSession) =>\n debugIntrospect || !userAndSession.sessions.some((sess) => sess.sessionId === SESSION_ID),\n ),\n ),\n map((userAndSessions) =>\n userAndSessions.map((userAndSession) => ({\n user: userAndSession.user,\n status: 'online',\n lastActiveAt: userAndSession.sessions.sort((a, b) =>\n b.lastActiveAt.localeCompare(a.lastActiveAt),\n )[0]?.lastActiveAt,\n locations: flatten(\n (userAndSession.sessions || []).map((session) => session.locations || []),\n )\n .map((location) => ({\n type: location.type,\n documentId: location.documentId,\n path: location.path,\n lastActiveAt: location.lastActiveAt,\n }))\n .reduce((prev, curr) => prev.concat(curr), [] as PresenceLocation[]),\n })),\n ),\n )\n\n // Create a single shared observable for all documents\n const allDocumentsPresence$ = combineLatest([allSessions$, debugIntrospect$]).pipe(\n map(([userAndSessions, debugIntrospect]) =>\n userAndSessions\n .flatMap((userAndSession) =>\n (userAndSession.session.locations || []).map((location) => ({\n documentId: location.documentId,\n presence: {\n user: userAndSession.user,\n lastActiveAt: userAndSession.session.lastActiveAt,\n path: location.path || [],\n sessionId: userAndSession.session.sessionId,\n selection: location?.selection,\n },\n })),\n )\n .filter((item) => debugIntrospect || item.presence.sessionId !== SESSION_ID),\n ),\n shareReplay(1),\n )\n\n /**\n * Returns document presence for the given documennt id\n * Presence are returned for all versions of the document\n */\n const documentPresence = (\n documentId: string,\n options?: {excludeVersions?: boolean},\n ): Observable<DocumentPresence[]> => {\n return allDocumentsPresence$.pipe(\n map((allPresence) =>\n allPresence\n .filter((item) =>\n options?.excludeVersions\n ? item.documentId === documentId\n : documentIdEquals(item.documentId, documentId),\n )\n .map((item) => ({\n ...item.presence,\n //documentId: getPublishedId(item.documentId),\n documentId: item.documentId,\n })),\n ),\n // Only emit if the presence has changed for this document id\n distinctUntilChanged((prev, curr) => isEqual(prev, curr)),\n )\n }\n\n return {setLocation, reportLocations, debugPresenceParam$, globalPresence$, documentPresence}\n}\n","import {type SanityClient} from '@sanity/client'\nimport {\n catchError,\n distinctUntilChanged,\n map,\n type Observable,\n of,\n repeat,\n ReplaySubject,\n scan,\n share,\n shareReplay,\n timer,\n} from 'rxjs'\n\nimport {memoize} from '../document/utils/createMemoizer'\nimport {createMemoKey, getClientCredentialSegments} from '../document/utils/memoKey'\nimport {type ProjectData, type ProjectGrants, type ProjectStore} from './types'\n\nconst REFETCH_INTERVAL = 5 * 60 * 1000 // 5 minutes\n\n// Memo key for the per-client request observables below. Must include the\n// credential, not just project/dataset — these poll `/projects` on a captured\n// client, so a stale-token entry would keep 401ing after a re-login (see\n// getClientCredentialSegments). The old entry goes idle when its last\n// subscriber leaves, but the memoizer never evicts, so its key and token string\n// are retained for the life of the page. Token stays in-memory (never logged).\nfunction projectRequestKey(client: SanityClient): string {\n return createMemoKey(getClientCredentialSegments(client))\n}\n\n/**\n * This value will be cached for 5 minutes, after that internal the cache will be refreshed.\n * If you need to be 100% sure the organizationId is up to date, you can call the `/projects/${projectId}` endpoint directly.\n */\nconst getProjectOrg = memoize((client: SanityClient) => {\n return client.observable\n .request<ProjectData>({\n url: `/projects/${client.config().projectId}`,\n tag: 'get-project-org',\n query: {\n includeMembers: 'false',\n includeFeatures: 'false',\n includeOrganization: 'true',\n },\n })\n .pipe(\n catchError(() => {\n return of(null)\n }),\n repeat({delay: REFETCH_INTERVAL}),\n // A transient refetch failure emits `null`. Retain the last known\n // project data so a failed refetch does not clobber a previously-good\n // organization id (which would strip org_id from telemetry events\n // flushed during the refetch window). See SAPP-3824.\n scan<ProjectData | null, ProjectData | null>((lastKnown, next) => next ?? lastKnown, null),\n distinctUntilChanged(),\n share({\n connector: () => new ReplaySubject(1),\n resetOnComplete: true,\n // delay unsubscriptions a little to keep the observable active\n // during React effect setup and teardown due to rapidly changing deps\n resetOnRefCountZero: () => timer(1000),\n }),\n )\n}, projectRequestKey)\n\nconst getOrganizationId = memoize(\n (client: SanityClient) => getProjectOrg(client).pipe(map((res) => res?.organizationId ?? null)),\n projectRequestKey,\n)\n\nconst getOrganizationData = memoize(\n (client: SanityClient) => getProjectOrg(client).pipe(map((res) => res?.organization ?? null)),\n projectRequestKey,\n)\n\n/**\n * Fetches the project grants for the current user, shared and replayed so all\n * permission checks reuse a single request. Memoized so callers outside the\n * project store (e.g. the schema/manifest upload gate) hit the same cached\n * observable instead of issuing a duplicate `/grants` request.\n *\n * Keyed by project/dataset **and credential** (see `projectRequestKey`),\n * matching the other memoized requests in this module, so a client for a\n * different project/dataset — or a new post-re-auth token — never reuses\n * another's grants.\n *\n * @internal\n */\nexport const getProjectGrants = memoize(\n (client: SanityClient): Observable<ProjectGrants> =>\n client.observable\n .request<ProjectGrants>({\n url: `/projects/${client.config().projectId}/grants`,\n tag: 'get-grants',\n })\n .pipe(shareReplay(1)),\n projectRequestKey,\n)\n\n/** @internal */\nexport function createProjectStore(context: {client: SanityClient}): ProjectStore {\n const {client} = context\n const projectId = client.config().projectId\n const versionedClient = client.withConfig({apiVersion: '2021-12-15'})\n\n function get(): Observable<ProjectData> {\n return versionedClient.observable.request({\n url: `/projects/${projectId}`,\n tag: 'get-project',\n })\n }\n\n function getDatasets() {\n return versionedClient.observable.request({\n url: `/projects/${projectId}/datasets`,\n tag: 'get-datasets',\n })\n }\n\n const projectOrgData$ = getProjectOrg(versionedClient)\n\n return {\n get,\n getDatasets,\n getGrants: () => getProjectGrants(versionedClient),\n getProjectName: () => projectOrgData$.pipe(map((res) => res?.displayName ?? null)),\n getOrganizationData: () => projectOrgData$.pipe(map((res) => res?.organization ?? null)),\n getOrganizationId: () => projectOrgData$.pipe(map((res) => res?.organizationId ?? null)),\n }\n}\n","import {type Observable} from 'rxjs'\n\n/**\n * @internal\n */\nexport type BaseStudioRenderingContext<\n Name extends string = string,\n Metadata = Record<PropertyKey, never>,\n> = {\n name: Name\n metadata: Metadata\n}\n\n/**\n * @internal\n */\nexport type DefaultRenderingContext = BaseStudioRenderingContext<'default'>\n\n/**\n * @internal\n */\nexport type CoreUiRenderingContext = BaseStudioRenderingContext<\n 'coreUi',\n {\n environment: string\n }\n>\n\n/**\n * @internal\n */\nexport type StudioRenderingContext = DefaultRenderingContext | CoreUiRenderingContext\n\n/**\n * @internal\n */\nexport const capabilities = ['globalUserMenu', 'globalWorkspaceControl', 'comlink'] as const\n\n/**\n * @internal\n */\nexport type Capability = (typeof capabilities)[number]\n\n/**\n * @internal\n */\nexport type CapabilityRecord = Partial<Record<Capability, boolean>>\n\n/**\n * @internal\n */\nexport type RenderingContextStore = {\n renderingContext: Observable<StudioRenderingContext>\n capabilities: Observable<CapabilityRecord>\n /**\n * The rendering context the store resolved when it was created — the value `renderingContext`\n * replays — for reading during render, where nothing may subscribe. `undefined` only while the\n * context is unresolved, which the store's own synchronous pipeline never is.\n */\n getRenderingContext: () => StudioRenderingContext | undefined\n /**\n * The capabilities of that rendering context — the value `capabilities` replays — for reading\n * during render, on the same terms as `getRenderingContext`.\n */\n getCapabilities: () => CapabilityRecord | undefined\n}\n\n/**\n * Check whether the provided value satisfies the `CoreUiRenderingContext` type.\n *\n * @internal\n */\nexport function isCoreUiRenderingContext(\n maybeCoreUiRenderingContext: unknown,\n): maybeCoreUiRenderingContext is CoreUiRenderingContext {\n return (\n typeof maybeCoreUiRenderingContext === 'object' &&\n maybeCoreUiRenderingContext !== null &&\n 'name' in maybeCoreUiRenderingContext &&\n maybeCoreUiRenderingContext.name === 'coreUi' &&\n 'metadata' in maybeCoreUiRenderingContext &&\n typeof maybeCoreUiRenderingContext.metadata === 'object' &&\n maybeCoreUiRenderingContext.metadata !== null &&\n 'environment' in maybeCoreUiRenderingContext.metadata &&\n typeof maybeCoreUiRenderingContext.metadata.environment === 'string'\n )\n}\n","import {\n catchError,\n distinctUntilChanged,\n map,\n of,\n type OperatorFunction,\n pipe,\n switchMap,\n} from 'rxjs'\n\nimport {isCoreUiRenderingContext, type StudioRenderingContext} from './types'\n\n// Core UI Rendering Context is provided via the URL query string, and remains static the entire\n// duration Studio is rendered inside the Core UI iframe.\n//\n// However, the URL query string is liable to be lost during Studio's lifecycle (for example, when\n// the user navigates to a different tool). Therefore, the URL query string is captured as soon as\n// this code is evaluated, and later referenced when a consumer subscribes to the store.\nconst INITIAL_URL_SEARCH = typeof location === 'object' ? location.search : ''\n\nconst CORE_UI_MODE_NAME = 'core-ui'\nconst CORE_UI_CONTEXT_SEARCH_PARAM = '_context'\n\n/**\n * @internal\n */\nexport function coreUiRenderingContext(\n urlSearch: string = INITIAL_URL_SEARCH,\n): OperatorFunction<StudioRenderingContext | undefined, StudioRenderingContext | undefined> {\n return pipe(\n switchMap((renderingContext) => {\n if (renderingContext) {\n return of(renderingContext)\n }\n\n return of(urlSearch).pipe(\n distinctUntilChanged(),\n map((search) => new URLSearchParams(search).get(CORE_UI_CONTEXT_SEARCH_PARAM)),\n map((serializedContext) => {\n if (serializedContext === null) {\n return undefined\n }\n\n const {mode, env} = JSON.parse(serializedContext)\n\n const coreUirenderingContext = {\n name: mode === CORE_UI_MODE_NAME ? 'coreUi' : undefined,\n metadata: {\n environment: env,\n },\n }\n\n if (isCoreUiRenderingContext(coreUirenderingContext)) {\n return coreUirenderingContext\n }\n\n return undefined\n }),\n catchError((error) => {\n console.warn('Error parsing rendering context:', error)\n return of(undefined)\n }),\n )\n }),\n )\n}\n","import {map, type OperatorFunction} from 'rxjs'\n\nimport {type DefaultRenderingContext, type StudioRenderingContext} from './types'\n\nconst DEFAULT_RENDERING_CONTEXT: DefaultRenderingContext = {\n name: 'default',\n metadata: {},\n}\n\n/**\n * @internal\n */\nexport function defaultRenderingContext(): OperatorFunction<\n StudioRenderingContext | undefined,\n StudioRenderingContext\n> {\n return map((renderingContext) => renderingContext ?? DEFAULT_RENDERING_CONTEXT)\n}\n","import {map, type OperatorFunction} from 'rxjs'\n\nimport {type CapabilityRecord, type StudioRenderingContext} from './types'\n\nconst capabilitiesByRenderingContext: Record<StudioRenderingContext['name'], CapabilityRecord> = {\n coreUi: {\n globalUserMenu: true,\n globalWorkspaceControl: true,\n comlink: true,\n },\n default: {},\n}\n\n/**\n * @internal\n */\nexport function listCapabilities(): OperatorFunction<StudioRenderingContext, CapabilityRecord> {\n return map((renderingContext) => capabilitiesByRenderingContext[renderingContext.name])\n}\n","import {of, shareReplay} from 'rxjs'\n\nimport {coreUiRenderingContext} from './coreUiRenderingContext'\nimport {defaultRenderingContext} from './defaultRenderingContext'\nimport {listCapabilities} from './listCapabilities'\nimport {\n type CapabilityRecord,\n type RenderingContextStore,\n type StudioRenderingContext,\n} from './types'\n\n/**\n * Rendering Context Store provides information about where Studio is being rendered, and which\n * capabilities are provided by the rendering context.\n *\n * This can be used to adapt parts of the Studio UI that are provided by the rendering context,\n * such as the global user menu.\n *\n * @param urlSearch - The URL query string to resolve the rendering context from; defaults to the\n * one captured when the studio booted.\n *\n * @internal\n */\nexport function createRenderingContextStore(urlSearch?: string): RenderingContextStore {\n const renderingContext = of(undefined).pipe(\n coreUiRenderingContext(urlSearch),\n defaultRenderingContext(),\n shareReplay(1),\n )\n\n const capabilities = renderingContext.pipe(listCapabilities(), shareReplay(1))\n\n // The context is static for the lifetime of the page and the pipeline resolves it synchronously\n // (the source completes right away), so connect both streams once here and keep the results:\n // consumers read them during render, where nothing may subscribe.\n let resolvedRenderingContext: StudioRenderingContext | undefined\n renderingContext.subscribe((value) => {\n resolvedRenderingContext = value\n })\n let resolvedCapabilities: CapabilityRecord | undefined\n capabilities.subscribe((value) => {\n resolvedCapabilities = value\n })\n\n return {\n renderingContext,\n capabilities,\n getRenderingContext: () => resolvedRenderingContext,\n getCapabilities: () => resolvedCapabilities,\n }\n}\n","interface MultiKeyWeakMapNode {\n type: 'multi-key-weak-map-node'\n value: unknown\n next: WeakMap<object, MultiKeyWeakMapNode>\n}\n\nexport interface MultiKeyWeakMap {\n get<T>(keys: object[]): T | undefined\n get(keys: object[]): unknown\n\n set(keys: object[], value: unknown): void\n}\n\nexport function createMultiKeyWeakMap(): MultiKeyWeakMap {\n const rootMap = new WeakMap<object, MultiKeyWeakMapNode>()\n const idCache = new WeakMap<object, string>()\n\n function randomId() {\n return Array.from({length: 10})\n .map(() =>\n Math.floor(Math.random() * 255)\n .toString(16)\n .padStart(2, '0'),\n )\n .join('')\n }\n\n function assignId(key: object) {\n const cachedId = idCache.get(key)\n if (cachedId) return cachedId\n const id = randomId()\n idCache.set(key, id)\n return id\n }\n\n function arrangeKeys(keys: object[]) {\n return Array.from(new Set(keys))\n .map((key) => [assignId(key), key] as const)\n .sort(([a], [b]) => a.localeCompare(b, 'en'))\n .map(([, key]) => key)\n }\n\n function getDeep(keys: object[], map: WeakMap<object, MultiKeyWeakMapNode>): unknown {\n if (!keys.length) return undefined\n const [firstKey, ...restOfKeys] = keys\n const node = map.get(firstKey)\n\n if (!node) return undefined\n if (!restOfKeys.length) return node.value\n return getDeep(restOfKeys, node.next)\n }\n\n function setDeep(\n keys: object[],\n map: WeakMap<object, MultiKeyWeakMapNode>,\n value: unknown,\n ): void {\n if (!keys.length) return\n\n const [firstKey, ...restOfKeys] = keys\n const node = map.get(firstKey) || {\n type: 'multi-key-weak-map-node',\n value: undefined,\n next: new WeakMap(),\n }\n map.set(firstKey, node)\n\n if (!restOfKeys.length) {\n node.value = value\n return\n }\n\n setDeep(restOfKeys, node.next, value)\n }\n\n function get<T>(keys: object[]): T | undefined\n function get(keys: object[]) {\n return getDeep(arrangeKeys(keys), rootMap)\n }\n\n function set(keys: object[], value: unknown) {\n setDeep(arrangeKeys(keys), rootMap, value)\n }\n\n return {get, set}\n}\n","import {type ReactNode, useContext, useState} from 'react'\nimport {ResourceCacheContext} from 'sanity/_singletons'\n\nimport {createMultiKeyWeakMap, type MultiKeyWeakMap} from './createMultiKeyWeakMap'\n\n/** @internal */\nexport interface ResourceCache {\n get<T = unknown>(options: {namespace: string; dependencies: (object | null)[]}): T | undefined\n set(options: {namespace: string; dependencies: (object | null)[]; value: unknown}): void\n}\n\n/** @internal */\nexport interface ResourceCacheProviderProps {\n children: ReactNode\n}\n\n/** @internal */\nexport function ResourceCacheProvider({children}: ResourceCacheProviderProps) {\n const [resourceCache] = useState((): ResourceCache => {\n const namespaces = new Map<string, MultiKeyWeakMap>()\n\n // this is used to replace the `null` values in any `dependencies` so that\n // they can be used in the `MultiKeyWeakMap` which doesn't accept null\n const nullReplacer = {}\n // this is used to replace `[]` dependencies to maintain the\n // same referential integrity in the weak map lookup\n const emptyDependenciesReplacer = [nullReplacer]\n\n const removeNullDependencies = (dependencies: (object | null)[]) =>\n dependencies.length\n ? dependencies.map((dep) => (dep === null ? nullReplacer : dep))\n : emptyDependenciesReplacer\n\n return {\n get: ({namespace, dependencies}) => {\n const dependenciesWithoutNull = removeNullDependencies(dependencies)\n const namespaceMap = namespaces.get(namespace)\n return namespaceMap?.get(dependenciesWithoutNull)\n },\n\n set: ({namespace, dependencies, value}) => {\n const namespaceMap = namespaces.get(namespace) || createMultiKeyWeakMap()\n const dependenciesWithoutNull = removeNullDependencies(dependencies)\n namespaces.set(namespace, namespaceMap)\n namespaceMap.set(dependenciesWithoutNull, value)\n },\n }\n })\n\n return (\n <ResourceCacheContext.Provider value={resourceCache}>{children}</ResourceCacheContext.Provider>\n )\n}\n\n/** @internal */\nexport function useResourceCache(): ResourceCache {\n const cache = useContext(ResourceCacheContext)\n if (!cache) throw new Error('Could not find `cache` context')\n return cache\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type CurrentUser, type User} from '@sanity/types'\nimport DataLoader from 'dataloader'\nimport raf from 'raf'\n\nimport {isRecord} from '../../util/isRecord'\n\n/** @internal */\nexport interface UserStoreOptions {\n client: SanityClient\n currentUser: CurrentUser | null\n}\n\nconst INTERNAL_USER_IDS: User[] = [\n {\n id: '<system>',\n displayName: 'Sanity',\n imageUrl: 'https://public.sanity.io/logos/favicon-192.png',\n },\n]\n\n/**\n * @hidden\n * @beta */\nexport interface UserStore {\n getUser(userId: string): Promise<User | null>\n getUsers(userIds: string[]): Promise<User[]>\n}\n\n/**\n * Given a `client` and a `currentUser` creates a datastore that handles\n * fetching, batch fetching, and caching users.\n *\n * @internal\n */\nexport function createUserStore({client: _client, currentUser}: UserStoreOptions): UserStore {\n const client = _client.withConfig({apiVersion: '2021-06-07'})\n\n const userLoader = new DataLoader<string, User | null>(\n async (userIds) => {\n const value = await client.request<(User | null)[]>({\n url: `/users/${userIds.join(',')}`,\n tag: 'users.get',\n })\n const response = Array.isArray(value) ? value : [value]\n const users = response.reduce(\n (acc, next) => {\n if (next?.id) {\n acc[next.id] = next\n }\n return acc\n },\n {} as Record<string, User | null>,\n )\n return userIds.map((id) => users[id] || null)\n },\n {\n batchScheduleFn: (cb) => raf(cb),\n /**\n * User IDs are generally 9 bytes long, but external user IDs may be longer.\n * In order to keep the HTTP header size below ~8KB, we limit the batch size.\n * ~4kB for user IDs in paths should allow for plenty of headers, if need be.\n */\n maxBatchSize: 400,\n },\n )\n\n const userFromCurrentUser: User | null = currentUser && {\n id: currentUser.id,\n displayName: currentUser.name,\n imageUrl: currentUser.profileImage,\n sanityUserId: currentUser.sanityUserId ?? undefined,\n }\n\n userLoader.prime('me', userFromCurrentUser)\n\n if (userFromCurrentUser?.id) {\n userLoader.prime(userFromCurrentUser.id, userFromCurrentUser)\n }\n\n INTERNAL_USER_IDS.forEach((user) => userLoader.prime(user.id, user))\n\n return {\n getUser: async (userId) => {\n if (!userId) return Promise.resolve(null)\n\n try {\n return await userLoader.load(userId)\n } catch (err) {\n /**\n * 403 Forbidden responses indicate that the current user doesn't have read access to project members.\n * In these instances, we don't throw and resolve `null` instead.\n * Components consuming this (such as `<UserAvatar>`) shouldn't render anything in these cases.\n */\n if (err.statusCode === 403) {\n return Promise.resolve(null)\n }\n // Throw all other errors\n throw err\n }\n },\n getUsers: async (userIds) => {\n const results = await userLoader.loadMany(userIds)\n /**\n * Unlike `load()`, DataLoader's `loadMany()` will always resolve even if it contains `Error` instances.\n * Here, we remove all Errors (or more specifically, only include records with valid IDs).\n */\n return results.filter(\n (result): result is User => isRecord(result) && typeof result.id === 'string',\n )\n },\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {useTelemetry} from '@sanity/telemetry/react'\nimport {useToast} from '@sanity/ui/toast'\nimport {useCallback, useEffect, useMemo} from 'react'\nimport {useSyncObservable} from 'react-rx'\n\nimport {useClient} from '../hooks/useClient'\nimport {useSchema} from '../hooks/useSchema'\nimport {useTemplates} from '../hooks/useTemplates'\nimport {useTranslation} from '../i18n/hooks/useTranslation'\nimport {\n createDocumentPreviewStore,\n type DocumentPreviewStore,\n} from '../preview/documentPreviewStore'\nimport {useStudioErrorHandler} from '../studio/requestErrors/useStudioErrorHandler'\nimport {useSource} from '../studio/source'\nimport {useWorkspace} from '../studio/workspace'\nimport {DEFAULT_STUDIO_CLIENT_OPTIONS} from '../studioClient'\nimport {createComlinkStore} from './comlink/createComlinkStore'\nimport {type ComlinkStore} from './comlink/types'\nimport {\n type ConnectionStatusStore,\n createConnectionStatusStore,\n} from './connection-status/connection-status-store'\nimport {DocumentDesynced} from './document/__telemetry__/documentOutOfSyncEvents.telemetry'\nimport {DocumentPairLoadingMeasured} from './document/__telemetry__/documentPairLoading.telemetry'\nimport {DocumentRebaseOccurred} from './document/__telemetry__/documentRebase.telemetry'\nimport {HighListenerLatencyOccurred} from './document/__telemetry__/listenerLatency.telemetry'\nimport {MutationPerformanceMeasured} from './document/__telemetry__/mutationPerformance.telemetry'\nimport {createDocumentStore, type DocumentStore} from './document/document-store'\nimport {\n type DocumentPairLoadedEvent,\n type DocumentRebaseTelemetryEvent,\n type LatencyReportEvent,\n type MutationPerformanceEvent,\n} from './document/getPairListener'\nimport {type OutOfSyncError} from './document/utils/sequentializeListenerEvents'\nimport {createGrantsStore} from './grants/grantsStore'\nimport {type GrantsStore} from './grants/types'\nimport {createHistoryStore, type HistoryStore} from './history/createHistoryStore'\nimport {createKeyValueStore} from './key-value/keyValueStore'\nimport {type KeyValueStore} from './key-value/types'\nimport {createPresenceStore, type PresenceStore} from './presence/presence-store'\nimport {createProjectStore} from './project/projectStore'\nimport {type ProjectStore} from './project/types'\nimport {createRenderingContextStore} from './renderingContext/createRenderingContextStore'\nimport {type CapabilityRecord, type RenderingContextStore} from './renderingContext/types'\nimport {useResourceCache} from './ResourceCacheProvider'\nimport {createUserStore, type UserStore} from './user/userStore'\n\n/**\n * Latencies below this value will not be logged\n */\nconst EMPTY_CAPABILITIES: CapabilityRecord = {}\n\nconst IGNORE_LATENCY_BELOW_MS = 1000\n\n/** Minimum time between slow commit toast notifications */\nconst SLOW_COMMIT_TOAST_COOLDOWN_MS = 30_000\nconst slowCommitCooldown = {lastToastAt: 0}\n\n/**\n * @hidden\n * @beta */\nexport function useUserStore(): UserStore {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const {getClient, currentUser} = useSource()\n const resourceCache = useResourceCache()\n const client = getClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n\n return useMemo(() => {\n const userStore =\n resourceCache.get<UserStore>({\n namespace: 'userStore',\n dependencies: [client, currentUser],\n }) || createUserStore({client, currentUser})\n\n resourceCache.set({\n namespace: 'userStore',\n dependencies: [client, currentUser],\n value: userStore,\n })\n\n return userStore\n }, [client, currentUser, resourceCache])\n}\n\n/**\n * @hidden\n * @beta */\nexport function useGrantsStore(): GrantsStore {\n // `currentUser` is read from the source directly (instead of via `useCurrentUser` from\n // `./user/hooks`) to avoid a circular import: `./user/hooks` imports `useUserStore` from here.\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const {getClient, currentUser} = useSource()\n const client = getClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n const resourceCache = useResourceCache()\n const errorHandler = useStudioErrorHandler()\n\n return useMemo(() => {\n const grantsStore =\n resourceCache.get<GrantsStore>({\n namespace: 'grantsStore',\n dependencies: [client, currentUser, errorHandler],\n }) || createGrantsStore({client, userId: currentUser?.id || null, errorHandler})\n\n resourceCache.set({\n namespace: 'grantsStore',\n dependencies: [client, currentUser, errorHandler],\n value: grantsStore,\n })\n\n return grantsStore\n }, [client, currentUser, errorHandler, resourceCache])\n}\n\n/**\n * @hidden\n * @beta */\nexport function useHistoryStore(): HistoryStore {\n const client = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n const resourceCache = useResourceCache()\n\n return useMemo(() => {\n const historyStore =\n resourceCache.get<HistoryStore>({\n namespace: 'historyStore',\n dependencies: [client],\n }) || createHistoryStore({client})\n\n resourceCache.set({\n namespace: 'historyStore',\n dependencies: [client],\n value: historyStore,\n })\n\n return historyStore\n }, [client, resourceCache])\n}\n\n/**\n * @hidden\n * @beta */\nexport function useDocumentPreviewStore(): DocumentPreviewStore {\n const client = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n const resourceCache = useResourceCache()\n\n return useMemo(() => {\n const documentPreviewStore =\n resourceCache.get<DocumentPreviewStore>({\n namespace: 'documentPreviewStore',\n dependencies: [client],\n }) || createDocumentPreviewStore({client})\n\n resourceCache.set({\n namespace: 'documentPreviewStore',\n dependencies: [client],\n value: documentPreviewStore,\n })\n\n return documentPreviewStore\n }, [client, resourceCache])\n}\n\n/**\n * @hidden\n * @beta */\nexport function useDocumentStore(): DocumentStore {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const {getClient, i18n, currentUser} = useSource()\n const schema = useSchema()\n const templates = useTemplates()\n const resourceCache = useResourceCache()\n const historyStore = useHistoryStore()\n const documentPreviewStore = useDocumentPreviewStore()\n const workspace = useWorkspace()\n const telemetry = useTelemetry()\n const toast = useToast()\n const {t} = useTranslation()\n const errorHandler = useStudioErrorHandler()\n\n const handleSyncErrorRecovery = useCallback(\n (error: OutOfSyncError) => {\n telemetry.log(DocumentDesynced, {errorName: error.name})\n },\n [telemetry],\n )\n\n const handleReportLatency = useCallback(\n (event: LatencyReportEvent) => {\n if (event.latencyMs > IGNORE_LATENCY_BELOW_MS) {\n telemetry.log(HighListenerLatencyOccurred, {\n latency: event.latencyMs,\n shard: event.shard,\n transactionId: event.transactionId,\n })\n }\n },\n [telemetry],\n )\n\n const handleSlowCommit = useCallback(() => {\n const now = Date.now()\n if (now - slowCommitCooldown.lastToastAt < SLOW_COMMIT_TOAST_COOLDOWN_MS) return\n slowCommitCooldown.lastToastAt = now\n toast.push({\n title: t('document-store.slow-commit.title'),\n description: t('document-store.slow-commit.description'),\n status: 'warning',\n })\n }, [toast, t])\n\n const handleDocumentPairLoaded = useCallback(\n (event: DocumentPairLoadedEvent) => {\n telemetry.log(DocumentPairLoadingMeasured, {\n durationMs: event.durationMs,\n fromCache: event.fromCache,\n hasPublished: event.hasPublished,\n hasDraft: event.hasDraft,\n hasVersion: event.hasVersion,\n })\n },\n [telemetry],\n )\n\n const handleReportMutationPerformance = useCallback(\n (event: MutationPerformanceEvent) => {\n telemetry.log(MutationPerformanceMeasured, event)\n },\n [telemetry],\n )\n\n const handleDocumentRebase = useCallback(\n (event: DocumentRebaseTelemetryEvent) => {\n telemetry.log(DocumentRebaseOccurred, event)\n },\n [telemetry],\n )\n\n return useMemo(() => {\n const documentStore =\n resourceCache.get<DocumentStore>({\n namespace: 'documentStore',\n dependencies: [\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n errorHandler,\n ],\n }) ||\n createDocumentStore({\n getClient,\n documentPreviewStore,\n historyStore,\n initialValueTemplates: templates,\n schema,\n i18n,\n currentUser,\n extraOptions: {\n onReportLatency: handleReportLatency,\n onSyncErrorRecovery: handleSyncErrorRecovery,\n onSlowCommit: handleSlowCommit,\n onDocumentPairLoaded: handleDocumentPairLoaded,\n onReportMutationPerformance: handleReportMutationPerformance,\n onDocumentRebase: handleDocumentRebase,\n snapshotFetchErrorHandler: errorHandler,\n },\n })\n\n resourceCache.set({\n namespace: 'documentStore',\n dependencies: [\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n errorHandler,\n ],\n value: documentStore,\n })\n\n return documentStore\n }, [\n resourceCache,\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n templates,\n handleReportLatency,\n handleSyncErrorRecovery,\n handleSlowCommit,\n handleDocumentPairLoaded,\n handleReportMutationPerformance,\n handleDocumentRebase,\n errorHandler,\n ])\n}\n\n/** @internal */\nexport function useConnectionStatusStore(): ConnectionStatusStore {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const {bifur} = useSource().__internal\n const resourceCache = useResourceCache()\n\n return useMemo(() => {\n const connectionStatusStore =\n resourceCache.get<ConnectionStatusStore>({\n namespace: 'connectionStatusStore',\n dependencies: [bifur],\n }) || createConnectionStatusStore({bifur})\n\n resourceCache.set({\n namespace: 'connectionStatusStore',\n dependencies: [bifur],\n value: connectionStatusStore,\n })\n\n return connectionStatusStore\n }, [bifur, resourceCache])\n}\n\n/**\n * @hidden\n * @beta */\nexport function usePresenceStore(): PresenceStore {\n const {\n __internal: {bifur},\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n } = useSource()\n const resourceCache = useResourceCache()\n const userStore = useUserStore()\n const connectionStatusStore = useConnectionStatusStore()\n\n return useMemo(() => {\n const presenceStore =\n resourceCache.get<PresenceStore>({\n namespace: 'presenceStore',\n dependencies: [bifur, connectionStatusStore, userStore],\n }) || createPresenceStore({bifur, connectionStatusStore, userStore})\n\n resourceCache.set({\n namespace: 'presenceStore',\n dependencies: [bifur, connectionStatusStore, userStore],\n value: presenceStore,\n })\n\n return presenceStore\n }, [bifur, connectionStatusStore, resourceCache, userStore])\n}\n\n/**\n * @hidden\n * @beta */\nexport function useProjectStore(): ProjectStore {\n const client = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n const resourceCache = useResourceCache()\n\n return useMemo(() => {\n const projectStore =\n resourceCache.get<ProjectStore>({\n namespace: 'projectStore',\n dependencies: [client],\n }) || createProjectStore({client})\n\n resourceCache.set({\n namespace: 'projectStore',\n dependencies: [client],\n value: projectStore,\n })\n\n return projectStore\n }, [client, resourceCache])\n}\n\n/**\n * Module-level cache for KeyValueStore instances, keyed by project identity.\n * Uses a simple Map with string keys since the ResourceCache's WeakMap\n * doesn't support primitive-based cache keys.\n */\nconst keyValueStoreCache = new Map<string, KeyValueStore>()\n\n/**\n * Generates a cache key for KeyValueStore based on project identity.\n * The /users/me/keyvalue endpoint is project-scoped, so we only need\n * projectId and apiHost (not dataset) to identify unique stores.\n */\nfunction getKeyValueStoreCacheKey(client: SanityClient): string {\n const config = client.config()\n return `${config.projectId}:${config.apiHost || 'default'}`\n}\n\n/**\n * Returns a KeyValueStore instance for storing user preferences.\n *\n * The store is cached by project identity (projectId + apiHost) rather than\n * workspace, because the /users/me/keyvalue endpoint is project-scoped -\n * user preferences are shared across all datasets within a project.\n *\n * @internal\n */\nexport function useKeyValueStore(): KeyValueStore {\n const client = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n\n return useMemo(() => {\n const cacheKey = getKeyValueStoreCacheKey(client)\n const cached = keyValueStoreCache.get(cacheKey)\n if (cached) return cached\n\n const keyValueStore = createKeyValueStore({client})\n keyValueStoreCache.set(cacheKey, keyValueStore)\n return keyValueStore\n }, [client])\n}\n\n/** @internal */\nexport function useRenderingContextStore(): RenderingContextStore {\n const resourceCache = useResourceCache()\n\n return useMemo(() => {\n const renderingContextStore =\n resourceCache.get<RenderingContextStore>({\n dependencies: [],\n namespace: 'RenderingContextStore',\n }) || createRenderingContextStore()\n\n resourceCache.set({\n dependencies: [],\n namespace: 'RenderingContextStore',\n value: renderingContextStore,\n })\n\n return renderingContextStore\n }, [resourceCache])\n}\n\n/** @internal */\nexport function useComlinkStore(): ComlinkStore {\n const resourceCache = useResourceCache()\n const renderingContext = useRenderingContextStore()\n // Kept synchronous: the comlink node is created when `capabilities.comlink`\n // is true, so a deferred snapshot would delay comlink initialization.\n // Capabilities emit once at boot; there is nothing to gain from deferring\n // them. The store has already resolved them, so the comlink store is created\n // for the actual capabilities right away instead of once for `{}` and again\n // after the first emission.\n const capabilities = useSyncObservable(\n renderingContext.capabilities,\n () => renderingContext.getCapabilities() ?? EMPTY_CAPABILITIES,\n )\n\n const comlinkStore = useMemo(() => {\n const store =\n resourceCache.get<ComlinkStore>({\n dependencies: [capabilities],\n namespace: 'ComlinkStore',\n }) || createComlinkStore({capabilities})\n\n resourceCache.set({\n dependencies: [capabilities],\n namespace: 'ComlinkStore',\n value: store,\n })\n\n return store\n }, [capabilities, resourceCache])\n\n // The store is created during render, which React may abandon; the node is\n // only started once a consumer commits. Starting is idempotent, so every\n // consumer may ask for it.\n useEffect(() => {\n comlinkStore.start()\n }, [comlinkStore])\n\n return comlinkStore\n}\n"],"x_google_ignoreList":[103],"mappings":"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"}
1
+ {"version":3,"file":"datastores-DNOJm1LF.js","names":["scan","switchMap","tap","{children}: ResourceCacheProviderProps","(): ResourceCache => {\n const namespaces = new Map<string, MultiKeyWeakMap>()\n\n // this is used to replace the `null` values in any `dependencies` so that\n // they can be used in the `MultiKeyWeakMap` which doesn't accept null\n const nullReplacer = {}\n // this is used to replace `[]` dependencies to maintain the\n // same referential integrity in the weak map lookup\n const emptyDependenciesReplacer = [nullReplacer]\n\n const removeNullDependencies = (dependencies: (object | null)[]) =>\n dependencies.length\n ? dependencies.map((dep) => (dep === null ? nullReplacer : dep))\n : emptyDependenciesReplacer\n\n return {\n get: ({namespace, dependencies}) => {\n const dependenciesWithoutNull = removeNullDependencies(dependencies)\n const namespaceMap = namespaces.get(namespace)\n return namespaceMap?.get(dependenciesWithoutNull)\n },\n\n set: ({namespace, dependencies, value}) => {\n const namespaceMap = namespaces.get(namespace) || createMultiKeyWeakMap()\n const dependenciesWithoutNull = removeNullDependencies(dependencies)\n namespaces.set(namespace, namespaceMap)\n namespaceMap.set(dependenciesWithoutNull, value)\n },\n }\n }","<ResourceCacheContext.Provider value={resourceCache}>{children}</ResourceCacheContext.Provider>","ResourceCacheContext.Provider","{namespace, dependencies}","dependencies","{namespace, dependencies, value}","namespaceMap","namespace","dependenciesWithoutNull","getClient(DEFAULT_STUDIO_CLIENT_OPTIONS)","useMemo(() => {\n const userStore =\n resourceCache.get<UserStore>({\n namespace: 'userStore',\n dependencies: [client, currentUser],\n }) || createUserStore({client, currentUser})\n\n resourceCache.set({\n namespace: 'userStore',\n dependencies: [client, currentUser],\n value: userStore,\n })\n\n return userStore\n }, [client, currentUser, resourceCache])","useMemo(() => {\n const grantsStore =\n resourceCache.get<GrantsStore>({\n namespace: 'grantsStore',\n dependencies: [client, currentUser, errorHandler],\n }) || createGrantsStore({client, userId: currentUser?.id || null, errorHandler})\n\n resourceCache.set({\n namespace: 'grantsStore',\n dependencies: [client, currentUser, errorHandler],\n value: grantsStore,\n })\n\n return grantsStore\n }, [client, currentUser, errorHandler, resourceCache])","useMemo(() => {\n const historyStore =\n resourceCache.get<HistoryStore>({\n namespace: 'historyStore',\n dependencies: [client],\n }) || createHistoryStore({client})\n\n resourceCache.set({\n namespace: 'historyStore',\n dependencies: [client],\n value: historyStore,\n })\n\n return historyStore\n }, [client, resourceCache])","useMemo(() => {\n const documentPreviewStore =\n resourceCache.get<DocumentPreviewStore>({\n namespace: 'documentPreviewStore',\n dependencies: [client],\n }) || createDocumentPreviewStore({client})\n\n resourceCache.set({\n namespace: 'documentPreviewStore',\n dependencies: [client],\n value: documentPreviewStore,\n })\n\n return documentPreviewStore\n }, [client, resourceCache])","(error: OutOfSyncError) => {\n telemetry.log(DocumentDesynced, {errorName: error.name})\n }","useCallback(\n (error: OutOfSyncError) => {\n telemetry.log(DocumentDesynced, {errorName: error.name})\n },\n [telemetry],\n )","(event: LatencyReportEvent) => {\n if (event.latencyMs > IGNORE_LATENCY_BELOW_MS) {\n telemetry.log(HighListenerLatencyOccurred, {\n latency: event.latencyMs,\n shard: event.shard,\n transactionId: event.transactionId,\n })\n }\n }","useCallback(\n (event: LatencyReportEvent) => {\n if (event.latencyMs > IGNORE_LATENCY_BELOW_MS) {\n telemetry.log(HighListenerLatencyOccurred, {\n latency: event.latencyMs,\n shard: event.shard,\n transactionId: event.transactionId,\n })\n }\n },\n [telemetry],\n )","() => {\n const now = Date.now()\n if (now - slowCommitCooldown.lastToastAt < SLOW_COMMIT_TOAST_COOLDOWN_MS) return\n slowCommitCooldown.lastToastAt = now\n toast.push({\n title: t('document-store.slow-commit.title'),\n description: t('document-store.slow-commit.description'),\n status: 'warning',\n })\n }","useCallback(() => {\n const now = Date.now()\n if (now - slowCommitCooldown.lastToastAt < SLOW_COMMIT_TOAST_COOLDOWN_MS) return\n slowCommitCooldown.lastToastAt = now\n toast.push({\n title: t('document-store.slow-commit.title'),\n description: t('document-store.slow-commit.description'),\n status: 'warning',\n })\n }, [toast, t])","(event: DocumentPairLoadedEvent) => {\n telemetry.log(DocumentPairLoadingMeasured, {\n durationMs: event.durationMs,\n fromCache: event.fromCache,\n hasPublished: event.hasPublished,\n hasDraft: event.hasDraft,\n hasVersion: event.hasVersion,\n })\n }","event","useCallback(\n (event: DocumentPairLoadedEvent) => {\n telemetry.log(DocumentPairLoadingMeasured, {\n durationMs: event.durationMs,\n fromCache: event.fromCache,\n hasPublished: event.hasPublished,\n hasDraft: event.hasDraft,\n hasVersion: event.hasVersion,\n })\n },\n [telemetry],\n )","(event: MutationPerformanceEvent) => {\n telemetry.log(MutationPerformanceMeasured, event)\n }","useCallback(\n (event: MutationPerformanceEvent) => {\n telemetry.log(MutationPerformanceMeasured, event)\n },\n [telemetry],\n )","(event: DocumentRebaseTelemetryEvent) => {\n telemetry.log(DocumentRebaseOccurred, event)\n }","useCallback(\n (event: DocumentRebaseTelemetryEvent) => {\n telemetry.log(DocumentRebaseOccurred, event)\n },\n [telemetry],\n )","useMemo(() => {\n const documentStore =\n resourceCache.get<DocumentStore>({\n namespace: 'documentStore',\n dependencies: [\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n errorHandler,\n ],\n }) ||\n createDocumentStore({\n getClient,\n documentPreviewStore,\n historyStore,\n initialValueTemplates: templates,\n schema,\n i18n,\n currentUser,\n extraOptions: {\n onReportLatency: handleReportLatency,\n onSyncErrorRecovery: handleSyncErrorRecovery,\n onSlowCommit: handleSlowCommit,\n onDocumentPairLoaded: handleDocumentPairLoaded,\n onReportMutationPerformance: handleReportMutationPerformance,\n onDocumentRebase: handleDocumentRebase,\n snapshotFetchErrorHandler: errorHandler,\n },\n })\n\n resourceCache.set({\n namespace: 'documentStore',\n dependencies: [\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n errorHandler,\n ],\n value: documentStore,\n })\n\n return documentStore\n }, [\n resourceCache,\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n templates,\n handleReportLatency,\n handleSyncErrorRecovery,\n handleSlowCommit,\n handleDocumentPairLoaded,\n handleReportMutationPerformance,\n handleDocumentRebase,\n errorHandler,\n ])","useMemo(() => {\n const connectionStatusStore =\n resourceCache.get<ConnectionStatusStore>({\n namespace: 'connectionStatusStore',\n dependencies: [bifur],\n }) || createConnectionStatusStore({bifur})\n\n resourceCache.set({\n namespace: 'connectionStatusStore',\n dependencies: [bifur],\n value: connectionStatusStore,\n })\n\n return connectionStatusStore\n }, [bifur, resourceCache])","{bifur}","useMemo(() => {\n const presenceStore =\n resourceCache.get<PresenceStore>({\n namespace: 'presenceStore',\n dependencies: [bifur, connectionStatusStore, userStore],\n }) || createPresenceStore({bifur, connectionStatusStore, userStore})\n\n resourceCache.set({\n namespace: 'presenceStore',\n dependencies: [bifur, connectionStatusStore, userStore],\n value: presenceStore,\n })\n\n return presenceStore\n }, [bifur, connectionStatusStore, resourceCache, userStore])","useMemo(() => {\n const projectStore =\n resourceCache.get<ProjectStore>({\n namespace: 'projectStore',\n dependencies: [client],\n }) || createProjectStore({client})\n\n resourceCache.set({\n namespace: 'projectStore',\n dependencies: [client],\n value: projectStore,\n })\n\n return projectStore\n }, [client, resourceCache])","useMemo(() => {\n const cacheKey = getKeyValueStoreCacheKey(client)\n const cached = keyValueStoreCache.get(cacheKey)\n if (cached) return cached\n\n const keyValueStore = createKeyValueStore({client})\n keyValueStoreCache.set(cacheKey, keyValueStore)\n return keyValueStore\n }, [client])","useMemo(() => {\n const renderingContextStore =\n resourceCache.get<RenderingContextStore>({\n dependencies: [],\n namespace: 'RenderingContextStore',\n }) || createRenderingContextStore()\n\n resourceCache.set({\n dependencies: [],\n namespace: 'RenderingContextStore',\n value: renderingContextStore,\n })\n\n return renderingContextStore\n }, [resourceCache])","() => renderingContext.getCapabilities() ?? EMPTY_CAPABILITIES","useMemo(() => {\n const store =\n resourceCache.get<ComlinkStore>({\n dependencies: [capabilities],\n namespace: 'ComlinkStore',\n }) || createComlinkStore({capabilities})\n\n resourceCache.set({\n dependencies: [capabilities],\n namespace: 'ComlinkStore',\n value: store,\n })\n\n return store\n }, [capabilities, resourceCache])","() => {\n comlinkStore.start()\n }","[comlinkStore]"],"sources":["../src/core/util/isRecord.ts","../src/core/util/postTask.ts","../src/core/templates/util/isRecord.ts","../src/core/templates/util/deepAssign.ts","../src/core/templates/validate.ts","../src/core/templates/resolve.ts","../src/core/hooks/useSchema.ts","../src/core/util/apiErrors.ts","../src/core/studio/requestErrors/classify.ts","../src/core/studio/requestErrors/createRequestErrorChannel.ts","../src/core/studio/requestErrors/useStudioErrorHandler.ts","../src/core/hooks/useTemplates.ts","../src/core/util/const.ts","../src/core/util/rxSwr.ts","../src/core/util/shallowEquals.ts","../src/core/preview/constants.tsx","../src/core/preview/utils/debounceCollect.ts","../src/core/preview/availability.ts","../src/core/preview/utils/shareReplayLatest.ts","../src/core/preview/createGlobalListener.ts","../src/core/preview/utils/applyMendozaPatch.ts","../src/core/preview/createObserveDocument.ts","../src/core/preview/utils/keysOf.ts","../src/core/preview/utils/props.ts","../src/core/preview/createPathObserver.ts","../src/core/preview/utils/getPreviewPaths.ts","../src/core/preview/utils/portableText.ts","../src/core/preview/utils/prepareForPreview.ts","../src/core/preview/createPreviewObserver.ts","../src/core/preview/documentPair.ts","../src/core/preview/liveDocumentIdSet.ts","../src/core/releases/util/releasesClient.ts","../src/core/variants/util/variantApiVersion.ts","../src/core/preview/utils/hasEqualFields.ts","../src/core/preview/utils/isUniqueBy.ts","../src/core/util/searchUtils.ts","../src/core/preview/utils/optimizeQuery.ts","../src/core/preview/observeFields.ts","../src/core/preview/observeVersionDocumentIds.ts","../src/core/preview/documentPreviewStore.ts","../src/core/store/comlink/createComlinkStore.ts","../src/core/util/catchWithCount.ts","../src/core/store/connection-status/connection-status-store.ts","../src/core/store/document/__telemetry__/documentOutOfSyncEvents.telemetry.ts","../src/core/store/document/__telemetry__/documentPairLoading.telemetry.ts","../src/core/store/document/__telemetry__/documentRebase.telemetry.ts","../src/core/store/document/__telemetry__/listenerLatency.telemetry.ts","../src/core/store/document/__telemetry__/mutationPerformance.telemetry.ts","../src/core/util/getDocumentVariantType.ts","../src/core/variants/tool/util.ts","../src/core/store/document/buffered-doc/createObservableBufferedDocument.ts","../src/core/store/document/buffered-doc/createBufferedDocument.ts","../src/core/store/document/debug.ts","../src/core/store/document/utils/dedupeListenerEvents.ts","../src/core/store/document/utils/eventChainUtils.ts","../src/core/store/document/utils/sequentializeListenerEvents.ts","../src/core/store/document/getPairListener.ts","../src/core/store/document/document-pair/utils/actionsApiClient.ts","../src/core/store/document/document-pair/utils/operationsApiClient.ts","../src/core/store/document/document-pair/checkoutPair.ts","../src/core/store/document/utils/createMemoizer.ts","../src/core/store/document/utils/memoKey.ts","../src/core/store/document/document-pair/memoizeKeyGen.ts","../src/core/store/document/document-pair/memoizedPair.ts","../src/core/store/document/document-pair/commitErrorStatus.ts","../src/core/store/document/document-pair/consistencyStatus.ts","../src/core/store/document/document-pair/documentEvents.ts","../src/core/store/document/document-pair/snapshotPair.ts","../src/core/store/document/document-pair/operationArgs.ts","../src/core/store/document/document-pair/getOperationStoreKey.ts","../src/core/store/document/document-pair/operations/commit.ts","../src/core/store/document/document-pair/utils/assertNotVariantVersion.ts","../src/core/store/document/document-pair/utils/isLiveEditEnabled.ts","../src/core/store/document/document-pair/operations/delete.ts","../src/core/store/document/document-pair/operations/discardChanges.ts","../src/core/variants/documents/getVariantVersionInfo.ts","../src/core/store/document/document-pair/operations/duplicate.ts","../src/core/store/document/document-pair/operations/patch.ts","../src/core/store/document/document-pair/operations/publish.ts","../src/core/store/document/document-pair/operations/restore.ts","../src/core/store/document/document-pair/operations/unpublish.ts","../src/core/store/document/document-pair/serverOperations/delete.ts","../src/core/store/document/document-pair/serverOperations/discardChanges.ts","../src/core/store/document/document-pair/serverOperations/patch.ts","../src/core/store/document/document-pair/serverOperations/publish.ts","../src/core/store/document/document-pair/serverOperations/restore.ts","../src/core/releases/util/isGoingToUnpublish.ts","../src/core/store/document/document-pair/serverOperations/unpublish.ts","../src/core/store/document/document-pair/operationEvents.ts","../src/core/store/document/document-pair/operations/helpers.ts","../src/core/store/document/document-pair/editOperations.ts","../src/core/releases/store/constants.ts","../src/core/releases/util/getReleaseIdFromReleaseDocumentId.ts","../src/core/util/measureFirstEmission.ts","../src/core/store/document/document-pair/editState.ts","../src/core/validation/validateDocumentWithReferences.ts","../src/core/validation/index.ts","../src/core/store/document/document-pair/validation.ts","../src/core/store/document/initialValue/initialValue.ts","../src/core/store/document/listenQuery.ts","../src/core/store/document/normalizeDocumentPairTarget.ts","../src/core/store/document/resolveTypeForDocument.ts","../src/core/store/document/document-store.ts","../../../node_modules/.pnpm/rxjs-etc@10.6.2_rxjs@7.8.2/node_modules/rxjs-etc/dist/esm/operators/refCountDelay.js","../src/core/store/debugParams/debugParams.ts","../src/core/store/grants/debug/exampleGrants.ts","../src/core/store/grants/debug/roleGrants.ts","../src/core/store/grants/grantsStore.ts","../src/core/environment/index.ts","../src/core/store/history/history/chunker.ts","../src/core/store/events/diffValue.ts","../src/core/store/history/history/diffValue.ts","../src/core/store/history/history/TwoEndedArray.ts","../src/core/store/history/history/utils.ts","../src/core/store/history/history/Timeline.ts","../src/core/store/events/getJsonStream.ts","../src/core/store/history/history/Aligner.ts","../src/core/store/history/history/Reconstruction.ts","../src/core/store/history/history/TimelineController.ts","../src/core/store/history/createHistoryStore.ts","../src/core/util/supportsLocalStorage.ts","../src/core/store/key-value/storage/memoryStorage.ts","../src/core/store/key-value/storage/localStoreStorage.ts","../src/core/store/key-value/localStorageSWR.ts","../src/core/store/key-value/storage/serverStorage.ts","../src/core/store/key-value/serverKeyValueStore.ts","../src/core/store/key-value/keyValueStore.ts","../src/core/store/presence/message-transports/bifurTransport.ts","../src/core/store/presence/mock-events.ts","../src/core/store/presence/presence-store.ts","../src/core/store/project/projectStore.ts","../src/core/store/renderingContext/types.ts","../src/core/store/renderingContext/coreUiRenderingContext.ts","../src/core/store/renderingContext/defaultRenderingContext.ts","../src/core/store/renderingContext/listCapabilities.ts","../src/core/store/renderingContext/createRenderingContextStore.ts","../src/core/store/createMultiKeyWeakMap.ts","../src/core/store/ResourceCacheProvider.tsx","../src/core/store/user/userStore.ts","../src/core/store/datastores.ts"],"sourcesContent":["/**\n * @internal\n */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n","/**\n * Schedule the provided callback using `scheduler.postTask`, if it's available.\n * Otherwise, call it immediately.\n */\nexport function postTask<Result>(\n callback: () => Result,\n options: PostTaskOptions = {},\n): Result | Promise<Result> {\n if ('scheduler' in window && typeof window.scheduler?.postTask === 'function') {\n return window.scheduler.postTask(callback, options)\n }\n return callback()\n}\n","import isPlainObject from 'lodash-es/isPlainObject.js'\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return isPlainObject(value)\n}\n","import {isRecord} from './isRecord'\n\n// deep object assign for objects\n// note: doesn't mutate target\nexport default function deepAssign(\n target: Record<string, unknown>,\n source: Record<string, unknown>,\n): Record<string, unknown> {\n const result = {...target, ...source}\n\n Object.keys(result).forEach((key) => {\n const sourceVal = source[key]\n const targetVal = target[key]\n if (isRecord(sourceVal) && isRecord(targetVal)) {\n result[key] = deepAssign(targetVal, sourceVal)\n }\n })\n return result\n}\n","import {type Schema} from '@sanity/types'\nimport {randomKey} from '@sanity/util/content'\nimport {toString as pathToString} from '@sanity/util/paths'\n\nimport {type Template, type TemplateParameter} from './types'\nimport {isRecord} from './util/isRecord'\n\nconst ALLOWED_REF_PROPS = [\n '_dataset',\n '_projectId',\n '_strengthenOnPublish',\n '_key',\n '_ref',\n '_type',\n '_weak',\n]\nconst REQUIRED_TEMPLATE_PROPS: (keyof Template)[] = ['id', 'title', 'schemaType', 'value']\n\nfunction templateId(template: Template, i: number) {\n return quote(template.id || template.title) || (typeof i === 'number' && `at index ${i}`) || ''\n}\n\nfunction quote(str: string) {\n return str && str.length > 0 ? `\"${str}\"` : str\n}\n\nexport function validateTemplates(schema: Schema, templates: Template[]): Template[] {\n const idMap = new Map()\n\n templates.forEach((template, i) => {\n const id = templateId(template, i)\n\n if (typeof (template as {[key: string]: any}).values !== 'undefined' && !template.value) {\n throw new Error(`Template ${id} is missing \"value\" property, but contained \"values\". Typo?`)\n }\n\n const missing = REQUIRED_TEMPLATE_PROPS.filter((prop) => !template[prop])\n if (missing.length > 0) {\n throw new Error(`Template ${id} is missing required properties: ${missing.join(', ')}`)\n }\n\n if (typeof template.value !== 'function' && !isRecord(template.value)) {\n throw new Error(\n `Template ${id} has an invalid \"value\" property; should be a function or an object`,\n )\n }\n\n if (typeof template.parameters !== 'undefined') {\n if (Array.isArray(template.parameters)) {\n template.parameters.forEach((param, j) => validateParameter(schema, param, template, j))\n } else {\n throw new Error(`Template ${id} has an invalid \"parameters\" property; must be an array`)\n }\n }\n\n if (idMap.has(template.id)) {\n const dupeIndex = idMap.get(template.id)\n const dupe = `${quote(templates[dupeIndex].title)} at index ${dupeIndex}`\n throw new Error(\n `Template \"${template.title}\" at index ${i} has the same ID (\"${template.id}\") as template ${dupe}`,\n )\n }\n\n idMap.set(template.id, i)\n })\n\n return templates\n}\n\nexport function validateInitialObjectValue<T extends Record<string, unknown>>(\n value: T,\n template: Template,\n): T {\n const contextError = (msg: string) => `Template \"${template.id}\" initial value: ${msg}`\n\n if (!isRecord(value)) {\n throw new Error(contextError(`resolved to a non-object`))\n }\n\n if (value._type && template.schemaType !== value._type) {\n throw new Error(\n contextError(\n `includes \"_type\"-property (${value._type}) that does not match template (${template.schemaType})`,\n ),\n )\n }\n\n try {\n return validateValue(value)\n } catch (err) {\n err.message = contextError(err.message)\n throw err\n }\n}\n\nfunction validateValue(value: unknown, path: (string | number)[] = [], parentIsArray = false): any {\n if (Array.isArray(value)) {\n return value.map((item, i) => {\n if (Array.isArray(item)) {\n throw new Error(\n `multidimensional arrays are not supported (at path \"${pathToString(path)}\")`,\n )\n }\n\n return validateValue(item, path.concat(i), true)\n })\n }\n\n if (!isRecord(value)) {\n return value\n }\n\n // Apply missing keys is the parent is an array\n const initial: {[key: string]: any} = parentIsArray && !value._key ? {_key: randomKey()} : {}\n\n // Ensure non-root objects have _type\n if (path.length > 0 && !value._type) {\n if (value._ref) {\n // In the case of references, we know what the type should be, so apply it\n initial._type = 'reference'\n } else {\n // todo: consider if we need to re-instantiate this. It currently makes the valid case of having an initial object value for a field fail\n // throw new Error(`missing \"_type\" property at path \"${pathToString(path)}\"`)\n }\n }\n\n if (value._ref) {\n validateReference(value, path)\n }\n\n // Validate deeply\n return Object.keys(value).reduce((acc, key) => {\n acc[key] = validateValue(value[key], path.concat([key]))\n return acc\n }, initial)\n}\n\nfunction validateParameter(\n schema: Schema,\n parameter: TemplateParameter,\n template: Template,\n index: number,\n) {\n // const schema = getDefaultSchema()\n\n if (!parameter.name) {\n throw new Error(\n `Template ${template.id} has a parameter at index ${index} that is missing its \"name\"-property`,\n )\n }\n\n // I know, this is a weird one\n if (parameter.name === 'template') {\n throw new Error(\n `Template parameters cannot be named \"template\", see parameter #${index} for template ${template.id}`,\n )\n }\n\n if (!schema.get(parameter.type)) {\n throw new Error(\n `Template parameter \"${parameter.name}\" has an invalid/unknown type: \"${parameter.type}\"`,\n )\n }\n}\n\nfunction validateReference(\n value: {_type?: unknown; type?: unknown},\n path: (string | number)[] = [],\n) {\n if (!value._type && value.type) {\n throw new Error(\n `Reference is missing \"_type\", but has a \"type\" property at path \"${pathToString(path)}\"`,\n )\n }\n\n const disallowed = Object.keys(value).filter((key) => !ALLOWED_REF_PROPS.includes(key))\n if (disallowed.length > 0) {\n const plural = disallowed.length > 1 ? 'properties' : 'property'\n throw new Error(\n `Disallowed ${plural} found in reference: ${disallowed\n .map(quote)\n .join(', ')} at path \"${pathToString(path)}\"`,\n )\n }\n}\n","import {\n type ArraySchemaType,\n type InitialValueProperty,\n type InitialValueResolver,\n type InitialValueResolverContext,\n isArraySchemaType,\n isObjectSchemaType,\n type ObjectSchemaType,\n type Schema,\n type SchemaType,\n} from '@sanity/types'\nimport {isDeepEmpty, randomKey, resolveTypeName} from '@sanity/util/content'\n\nimport {postTask} from '../util/postTask'\nimport {type Template} from './types'\nimport deepAssign from './util/deepAssign'\nimport {isRecord} from './util/isRecord'\nimport {validateInitialObjectValue} from './validate'\n\n/** @internal */\nexport type Serializeable<T> = {\n serialize(): T\n}\n\ninterface Options {\n useCache?: boolean\n}\n\n/** @internal */\nexport function isBuilder(template: unknown): template is Serializeable<Template> {\n return isRecord(template) && typeof template.serialize === 'function'\n}\n\nconst cache = new WeakMap<\n InitialValueResolver<unknown, unknown>,\n Record<string, unknown | Promise<unknown>>\n>()\n\n/** @internal */\n// returns the \"resolved\" value from an initial value property (e.g. type.initialValue)\nexport async function resolveValue<Params, InitialValue>(\n initialValueOpt: InitialValueProperty<Params, InitialValue>,\n params: Params | undefined,\n context: InitialValueResolverContext,\n options?: Options,\n): Promise<InitialValue | undefined> {\n const useCache = options?.useCache\n\n if (typeof initialValueOpt === 'function') {\n const cached = cache.get(initialValueOpt as InitialValueResolver<unknown, unknown>)\n\n const key = JSON.stringify([\n params,\n context.projectId,\n context.dataset,\n context.currentUser?.id,\n ])\n\n if (useCache && cached?.[key]) {\n return cached[key] as InitialValue | Promise<InitialValue>\n }\n\n const value = (initialValueOpt as InitialValueResolver<Params, InitialValue>)(params, context)\n\n if (useCache) {\n cache.set(initialValueOpt as InitialValueResolver<unknown, unknown>, {\n ...cached,\n [key]: value,\n })\n }\n\n return value\n }\n\n return initialValueOpt\n}\n\n/** @internal */\nexport async function resolveInitialValue(\n schema: Schema,\n template: Template,\n params: {[key: string]: any} = {},\n context: InitialValueResolverContext,\n options?: Options,\n): Promise<{[key: string]: any}> {\n // Template builder?\n if (isBuilder(template)) {\n return resolveInitialValue(schema, template.serialize(), params, context, options)\n }\n\n const {id, schemaType: schemaTypeName, value} = template\n if (!value) {\n throw new Error(`Template \"${id}\" has invalid \"value\" property`)\n }\n\n let resolvedValue = await resolveValue(value, params, context, options)\n\n if (!isRecord(resolvedValue)) {\n throw new Error(\n `Template \"${id}\" has invalid \"value\" property - must be a plain object or a resolver function returning a plain object`,\n )\n }\n\n // Ensure _type is set on empty objects\n if (isRecord(resolvedValue) && !Object.keys(resolvedValue).length) {\n resolvedValue = {_type: schemaTypeName}\n }\n\n // validate default document initial values\n resolvedValue = validateInitialObjectValue(resolvedValue, template)\n\n // Get deep initial values from schema types (note: the initial value from template overrides the types)\n const schemaType = schema.get(schemaTypeName)\n if (!schemaType) {\n throw new Error(`Could not find schema type with name \"${schemaTypeName}\".`)\n }\n\n const newValue = deepAssign(\n (await resolveInitialValueForType(\n schemaType,\n params,\n DEFAULT_MAX_RECURSION_DEPTH,\n context,\n options,\n )) || {},\n resolvedValue as Record<string, unknown>,\n )\n\n // revalidate and return new initial values\n // todo: would be better to do validation as part of type resolution\n return validateInitialObjectValue(newValue, template)\n}\n\n/** @internal */\nfunction getItemType(arrayType: ArraySchemaType, item: unknown): SchemaType | undefined {\n const itemTypeName = resolveTypeName(item)\n\n return itemTypeName === 'object' && arrayType.of.length === 1\n ? arrayType.of[0]\n : arrayType.of.find((memberType) => memberType.name === itemTypeName)\n}\n\n/** @internal */\nexport const DEFAULT_MAX_RECURSION_DEPTH = 10\n\n/**\n * Backstop for an initial-value resolver whose request never settles — e.g.\n * a `client.fetch` parked by the studio's network/CORS error handling.\n * Without it the editor hangs in a loading state and the create-document menu\n * loads forever instead of surfacing the failure. Both call sites\n * (`getInitialValueStream`, `getTemplatePermissions`) time out on this bound.\n *\n * @internal\n */\nexport const RESOLVE_INITIAL_VALUE_TIMEOUT_MS = 10_000\n\ntype ResolveInitialValueForType = <TParams extends Record<string, unknown>>(\n /**\n * This is the name of the document.\n */ type: SchemaType,\n /**\n * Params is a sanity context object passed to every initial value function.\n */\n params: TParams,\n /**\n * Maximum recursion depth (default 9).\n */\n maxDepth: number,\n context: InitialValueResolverContext,\n options?: Options,\n) => Promise<any>\n\nconst memoizeResolveInitialValueForType: (\n fn: ResolveInitialValueForType,\n) => ResolveInitialValueForType = (fn) => {\n const resolveInitialValueForTypeCache = new WeakMap<SchemaType, Map<string, Promise<any>>>()\n\n const stableStringify = (obj: any): string => {\n if (obj !== null && typeof obj === 'object') {\n if (Array.isArray(obj)) {\n return `[${obj.map(stableStringify).join(',')}]`\n }\n const keys = Object.keys(obj).sort()\n return `{${keys\n .map((key) => `${JSON.stringify(key)}:${stableStringify(obj[key])}`)\n .join(',')}}`\n }\n return JSON.stringify(obj)\n }\n\n const hashParameters = (\n params: Record<string, unknown>,\n context: InitialValueResolverContext,\n ): string => {\n return stableStringify({\n params,\n context: {\n schemaName: context.schema.name,\n projectId: context.projectId,\n dataset: context.dataset,\n currentUser: context.currentUser?.id,\n },\n })\n }\n\n return async function resolveInitialValueForType(type, params, maxDepth, context, options) {\n if (!options?.useCache) return fn(type, params, maxDepth, context, options)\n\n let typeCache = resolveInitialValueForTypeCache.get(type)\n\n if (!typeCache) {\n typeCache = new Map<string, Promise<any>>()\n resolveInitialValueForTypeCache.set(type, typeCache)\n }\n\n const hash = hashParameters(params, context)\n\n const cachedResult = typeCache.get(hash)\n if (cachedResult) return cachedResult\n\n const result = await fn(type, params, maxDepth, context, options)\n\n // double check after the await\n if (!typeCache.has(hash)) {\n typeCache.set(hash, result)\n }\n return result\n }\n}\n\n/**\n * Resolve initial value for the given schema type (recursively)\n *\n * @internal\n */\nexport const resolveInitialValueForType = memoizeResolveInitialValueForType(\n (type, params, maxDepth = DEFAULT_MAX_RECURSION_DEPTH, context, options): Promise<any> => {\n if (maxDepth <= 0) {\n return Promise.resolve(undefined)\n }\n\n if (isObjectSchemaType(type)) {\n return postTask(() => resolveInitialObjectValue(type, params, maxDepth, context, options))\n }\n\n if (isArraySchemaType(type)) {\n return postTask(() => resolveInitialArrayValue(type, params, maxDepth, context, options))\n }\n\n return resolveValue(type.initialValue, params, context, options)\n },\n)\n\nasync function resolveInitialArrayValue<Params extends Record<string, unknown>>(\n type: SchemaType,\n params: Params,\n maxDepth: number,\n context: InitialValueResolverContext,\n options?: Options,\n): Promise<any> {\n const initialArray = await resolveValue(type.initialValue, undefined, context, options)\n\n if (!Array.isArray(initialArray)) {\n return undefined\n }\n\n return Promise.all(\n initialArray.map(async (initialItem) => {\n const itemType = getItemType(type as ArraySchemaType, initialItem)!\n return isObjectSchemaType(itemType)\n ? {\n // The initial value defined on the parent array field takes precedence over\n // initial values resolved from the array member type's own fields.\n ...deepAssign(\n (await resolveInitialValueForType(\n itemType,\n params,\n maxDepth - 1,\n context,\n options,\n )) || {},\n initialItem as Record<string, unknown>,\n ),\n _key: randomKey(),\n }\n : initialItem\n }),\n )\n}\n\n/** @internal */\nexport async function resolveInitialObjectValue<Params extends Record<string, unknown>>(\n type: ObjectSchemaType,\n params: Params,\n maxDepth: number,\n context: InitialValueResolverContext,\n options?: Options,\n): Promise<any> {\n const initialObject: Record<string, unknown> = {\n ...((await resolveValue(type.initialValue, params, context, options)) || {}),\n }\n\n const fieldValues: Record<string, any> = {}\n await Promise.all(\n type.fields.map(async (field) => {\n const initialFieldValue = await resolveInitialValueForType(\n field.type,\n params,\n maxDepth - 1,\n context,\n options,\n )\n if (initialFieldValue !== undefined && initialFieldValue !== null) {\n fieldValues[field.name] = initialFieldValue\n }\n }),\n )\n\n const merged = deepAssign(fieldValues, initialObject)\n\n if (isDeepEmpty(merged)) {\n return undefined\n }\n\n if (type.name !== 'object') {\n merged._type = type.name\n }\n\n return merged\n}\n","import {type Schema} from '@sanity/types'\n\nimport {useSource} from '../studio/source'\n\n/**\n * React hook that returns the schema registry for the current project\n *\n * @public\n * @returns The schema registry for the current project\n * @example Using the `useSchema` hook\n * ```ts\n * function MyComponent() {\n * const schema = useSchema()\n * // ... do something with the schema ...\n * }\n * ```\n */\nexport function useSchema(): Schema {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n return useSource().schema\n}\n","import {type ConnectionFailedError, type HttpError, isHttpError} from '@sanity/client'\n\n/** @internal */\nexport function isUnauthorizedError(err: unknown): err is HttpError {\n return isHttpError(err) && err.statusCode === 401\n}\n\n/**\n * Whether `err` is a listener/live-events connection the client rejected with a\n * 401. Unlike a data request, the `listen` endpoint never answers 403: access\n * is applied by filtering events, so a rejected connection can only be an\n * invalid or expired session. The rejection is a `ConnectionFailedError`\n * carrying only `status` (no response body, so no `errorCode`), matched by name\n * to survive duplicate `@sanity/client` copies.\n *\n * @internal\n */\nexport function isConnectionSessionError(err: unknown): err is ConnectionFailedError {\n return (\n err instanceof Error &&\n err.name === 'ConnectionFailedError' &&\n 'status' in err &&\n err.status === 401\n )\n}\n\n/**\n * Error codes the API uses on 401s that positively signal an invalid session:\n * - `SIO-401-AEX`: the session has expired\n * - `SIO-401-ANF`: the token resolves to no session at all (\"Session not\n * found\" — revoked on another device, purged after expiry, or a stale/\n * corrupted stored token)\n *\n * Both mean no valid session exists, so both warrant a forced logout.\n */\nconst INVALID_SESSION_ERROR_CODES = ['SIO-401-AEX', 'SIO-401-ANF']\n\n/**\n * Whether a 401 positively signals an invalid session (see\n * {@link INVALID_SESSION_ERROR_CODES}). A 401 *without* one of these codes is\n * a resource-level denial (e.g. an authenticated user lacking a grant —\n * some endpoints answer those with 401, not 403) and must stay\n * caller-domain rather than force a logout; grant denials only happen with\n * a valid session, so they never carry these codes.\n *\n * @internal\n */\nexport function isInvalidSessionError(err: unknown): err is HttpError {\n if (!isUnauthorizedError(err)) return false\n const code = getApiErrorCode(err)\n return code !== undefined && INVALID_SESSION_ERROR_CODES.includes(code)\n}\n\n/**\n * The API's machine-readable `errorCode` from a client error response body\n * (e.g. `SIO-401-AEX` for an expired session), or `undefined` if absent. The\n * `ClientError` exposes the parsed body on `response.body` (typed `unknown`);\n * fall back to the stringified `responseBody` since older error shapes only\n * carry that.\n *\n * @internal\n */\nexport function getApiErrorCode(err: unknown): string | undefined {\n if (!isHttpError(err)) return undefined\n const fromResponse = readErrorCode(err.response.body)\n if (fromResponse) return fromResponse\n const responseBody = 'responseBody' in err ? err.responseBody : undefined\n if (typeof responseBody !== 'string') return undefined\n try {\n return readErrorCode(JSON.parse(responseBody))\n } catch {\n return undefined\n }\n}\n\nfunction readErrorCode(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null || !('errorCode' in value)) return undefined\n const code = value.errorCode\n return typeof code === 'string' ? code : undefined\n}\n","import {type HttpError, isHttpError, isTimeoutError} from '@sanity/client'\nimport isNativeNetworkError from 'is-network-error'\n\n// These live in `util` so that non-studio code (e.g. the document store) can\n// depend on them without importing from `studio`; re-exported here to keep\n// the public API surface and existing import sites unchanged.\nexport {getApiErrorCode, isInvalidSessionError, isUnauthorizedError} from '../../util/apiErrors'\nexport {isTimeoutError}\n\n/**\n * Node / get-it v8 timeout codes. get-it v9 reports timeouts as\n * `TimeoutError` (caught by {@link isTimeoutError}); older transports used\n * `ESOCKETTIMEDOUT` (idle socket) or `ETIMEDOUT` (connect/request deadline)\n * on a plain Error, which `isTimeoutError` no longer matches.\n */\nconst LEGACY_TIMEOUT_CODES = new Set(['ESOCKETTIMEDOUT', 'ETIMEDOUT'])\n\n/**\n * Timeouts the studio should treat as infrastructure failures and must not\n * diagnose via `/check/cors` (the probe would just time out too). Covers\n * get-it v9 / platform `TimeoutError` and leftover get-it v8 / Node codes.\n *\n * @internal\n */\nexport function isRequestTimeoutError(error: unknown): error is Error {\n if (isTimeoutError(error)) return true\n if (typeof error !== 'object' || error === null) return false\n return 'code' in error && typeof error.code === 'string' && LEGACY_TIMEOUT_CODES.has(error.code)\n}\n\n/** @internal */\nexport function isNetworkError(error: unknown): error is Error {\n if (typeof error !== 'object' || error === null) return false\n // get-it sets isNetworkError=true on connection errors.\n if ('isNetworkError' in error && error.isNetworkError === true) return true\n // Treat both get-it header timeouts and platform request-deadline\n // TimeoutErrors as network errors so they get the same treatment.\n if (isRequestTimeoutError(error)) return true\n return isNativeNetworkError(error)\n}\n\n/**\n * Read the Retry-After header off a ClientError, if present. Per RFC 7231,\n * it's either a non-negative delta-seconds integer or an HTTP date.\n *\n * @internal\n */\nexport function parseRetryAfter(err: HttpError): number | undefined {\n const value = err.response.headers['retry-after']\n if (!value) return undefined\n // Numeric-looking values go through the integer path even when out of\n // range, so negative numbers don't accidentally fall through to the date\n // parser (which can interpret them as historic dates).\n if (/^-?\\d+(\\.\\d+)?$/.test(value.trim())) {\n const seconds = Number(value)\n if (Number.isFinite(seconds) && seconds >= 0) return Math.ceil(seconds)\n return undefined\n }\n const dateMs = Date.parse(value)\n if (Number.isFinite(dateMs)) {\n const delta = Math.ceil((dateMs - Date.now()) / 1000)\n return delta > 0 ? delta : 0\n }\n return undefined\n}\n\n/**\n * Infrastructure-level error variants the studio's request-error UI knows\n * how to render. Everything else (4xx other than 429, parse errors, etc.)\n * is caller-domain and is never claimed by the studio.\n *\n * @internal\n */\nexport type RequestErrorClassification =\n | {type: 'networkError'; error: Error}\n | {type: 'serverError'; error: HttpError}\n | {type: 'rateLimited'; error: HttpError; retryAfterSeconds?: number}\n\n/**\n * Classify an error as an infrastructure-level request failure, or return\n * `null` when the error is caller-domain (validation errors, permission\n * denials, conflicts, 404s, ...) and should stay with the caller.\n *\n * Note: 401 is intentionally NOT classified here — whether a 401 means\n * \"invalid session\" (studio concern) or \"this resource refuses you\"\n * (caller concern) is decided by the API's explicit error code, which the\n * channel checks separately (see {@link isInvalidSessionError}).\n *\n * @internal\n */\nexport function classifyRequestError(err: unknown): RequestErrorClassification | null {\n if (isHttpError(err)) {\n if (err.statusCode === 429) {\n return {type: 'rateLimited', error: err, retryAfterSeconds: parseRetryAfter(err)}\n }\n if (err.statusCode >= 500) return {type: 'serverError', error: err}\n // 4xx other than 429 are caller-domain. They carry structured context\n // the caller is better positioned to render than a generic dialog.\n return null\n }\n if (isNetworkError(err)) return {type: 'networkError', error: err}\n return null\n}\n\n/**\n * A workspace-level configuration error: the project or dataset the\n * studio is pointed at doesn't exist. Unlike the infrastructure errors\n * above, these are not transient and not recoverable by retry — the user\n * has to fix `projectId`/`dataset` in their config (or create the missing\n * resource). The studio surfaces these as a full-screen takeover rather\n * than the retry/reload dialog.\n *\n * Which variant we can report depends on what the failing endpoint tells\n * us. Only the project/dataset management API carries a structured\n * discriminator; the generic `/data` 404 can't tell missing-project from\n * missing-dataset apart, so it isn't classified as a config error at all\n * (see {@link classifyConfigError}).\n *\n * @internal\n */\nexport type ConfigErrorClassification = {type: 'projectNotFound'} | {type: 'datasetNotFound'}\n\n/** Shape of the structured fields we read off a 404 response body. */\ninterface NotFoundBody {\n error?: unknown\n attributes?: {type?: unknown}\n}\n\nfunction notFoundBody(err: HttpError): NotFoundBody | undefined {\n const body = err.response.body\n if (!body || typeof body !== 'object') return undefined\n\n const attributes = 'attributes' in body ? body.attributes : undefined\n return {\n error: 'error' in body ? body.error : undefined,\n attributes:\n attributes && typeof attributes === 'object'\n ? {type: 'type' in attributes ? attributes.type : undefined}\n : undefined,\n }\n}\n\n/**\n * Classify a 404 as a studio-configuration error — the project or dataset\n * the studio points at doesn't exist — using only structured response\n * fields (never message text, which isn't stable across endpoints).\n *\n * Recognized structured signals:\n * - `attributes.type === 'project'` → `projectNotFound`\n * (project management API)\n * - `error === 'Dataset not found'` → `datasetNotFound`\n * (dataset management API; a discrete error code, not free-form text)\n *\n * A 404 without one of these structured signals returns `null` and stays\n * caller-domain — including the generic `/data` 404s, which carry no\n * discriminator and so can't be safely attributed to a missing project or\n * dataset. This classifier only reports what the *response* proves.\n *\n * @internal\n */\nexport function classifyConfigError(err: unknown): ConfigErrorClassification | null {\n if (!isHttpError(err) || err.statusCode !== 404) return null\n const body = notFoundBody(err)\n if (!body) return null\n\n // Project management API tags the response with `attributes.type`.\n if (body.attributes?.type === 'project') {\n return {type: 'projectNotFound'}\n }\n\n // Dataset management API returns a discrete `error` code. This is an\n // equality check on a structured field, not a match against free-form\n // `message` text.\n if (body.error === 'Dataset not found') {\n return {type: 'datasetNotFound'}\n }\n\n return null\n}\n\n/**\n * Whether an error originates from a Sanity client request — i.e. one a\n * plugin/customization could have delegated to the studio's error UI via\n * `useStudioErrorHandler()` rather than letting it reach an error\n * boundary. Used to surface a dev-only \"did you mean to opt in?\" tip.\n *\n * @internal\n */\nexport function isClientRequestError(err: unknown): boolean {\n return isHttpError(err) || isNetworkError(err)\n}\n","import {type HttpError} from '@sanity/client'\nimport {BehaviorSubject, isObservable, lastValueFrom, type Observable} from 'rxjs'\n\nimport {classifyRequestError, isInvalidSessionError} from './classify'\nimport {\n type RequestErrorChannel,\n type RequestErrorClaim,\n type RequestErrorReportOptions,\n type StudioErrorHandler,\n} from './types'\n\n/**\n * Best-effort projectId extraction from an HTTP error's request URL\n * (`https://{projectId}.api.sanity.io/...`). Used to route a delegated\n * 401 to the right workspace's auth store for forced logout.\n */\nfunction projectIdFromError(err: HttpError): string | undefined {\n const url = err.response.url\n if (!url) return undefined\n try {\n const host = new URL(url).hostname\n const match = host.match(/^([a-z0-9]+)\\.api\\.sanity\\.(?:io|work)$/)\n return match?.[1]\n } catch {\n return undefined\n }\n}\n\ninterface ParkedEntry {\n /** Re-runs the failed work. Absent for the `handle()` form. */\n retry?: () => void\n}\n\n/**\n * Create the studio's request-error channel. Framework-free — the React\n * side (context provider, dialog rendering) lives in `WorkspacesProvider`.\n *\n * See {@link StudioErrorHandler} for the call-site API and semantics.\n *\n * @internal\n */\nexport function createRequestErrorChannel(): RequestErrorChannel {\n const claimSubject = new BehaviorSubject<RequestErrorClaim | undefined>(undefined)\n let parked: ParkedEntry[] = []\n\n /**\n * Attempt to claim `err` for the studio UI. Returns `true` when claimed\n * (entry parked, dialog state set) and `false` when the error is\n * caller-domain and should be re-thrown by the caller of this function.\n */\n function tryClaim(err: unknown, options: RequestErrorReportOptions, entry: ParkedEntry): boolean {\n if (isInvalidSessionError(err)) {\n // The API positively signals an invalid session (expired or not found,\n // see INVALID_SESSION_ERROR_CODES) — force logout. A 401 *without* such\n // a code is a resource-level denial (some endpoints answer 401, not\n // 403, for authenticated users lacking a grant) and stays\n // caller-domain, same as a 403.\n parked.push(entry)\n // First invalid-session 401 owns the dialog + logout; concurrent\n // ones for the same teardown (including the logout request's own\n // 401) just park behind it rather than re-claiming.\n if (claimSubject.getValue()?.type !== 'unauthorized') {\n claimSubject.next({type: 'unauthorized', error: err, projectId: projectIdFromError(err)})\n }\n return true\n }\n\n const classification = classifyRequestError(err)\n if (!classification) return false\n\n parked.push(entry)\n // First claim owns the dialog; later concurrent failures just park —\n // their retries piggyback on the visible dialog's \"Try again\".\n if (!claimSubject.getValue()) {\n claimSubject.next({\n ...classification,\n retryable: Boolean(options.retryable && entry.retry),\n })\n }\n return true\n }\n\n function retry(): void {\n const entries = parked\n parked = []\n claimSubject.next(undefined)\n for (const entry of entries) {\n // Entries without a retry mechanism (the `handle()` form) stay\n // parked-forever by design: their promise chains were\n // fire-and-surface. Re-running is only possible where the caller\n // gave us something to run.\n entry.retry?.()\n }\n }\n\n async function handle(err: unknown): Promise<never> {\n // A rejection handler can't re-run the request (it already happened),\n // so handled errors are never retryable.\n if (!tryClaim(err, {retryable: false}, {})) throw err\n // Claimed: the dialog is up. Park the chain — there is nothing to\n // re-run, so it stays pending until the user reloads.\n return new Promise<never>(() => {})\n }\n\n function attempt<T>(\n thunk: (attemptNumber: number) => PromiseLike<T> | Observable<T>,\n options: RequestErrorReportOptions = {},\n ): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let attemptNumber = 0\n const tryOnce = () => {\n attemptNumber += 1\n Promise.resolve(attemptNumber)\n .then((n) => {\n const result = thunk(n)\n // Single-shot request observables emit once then complete —\n // their last value is their value.\n return isObservable(result) ? lastValueFrom(result) : result\n })\n .then(resolve, (err) => {\n if (!tryClaim(err, options, {retry: tryOnce})) reject(err)\n })\n }\n tryOnce()\n })\n }\n\n return {\n attempt,\n handle,\n retry,\n claim$: claimSubject.asObservable(),\n }\n}\n\n/**\n * The {@link StudioErrorHandler} used when there is no studio error UI to\n * delegate to — outside a `WorkspacesProvider`, or in a standalone render\n * of a component that normally lives in a Studio.\n *\n * It has no dialog and no retry, so it just runs the work and lets the\n * caller's own error handling take over:\n * - `attempt()` runs the thunk once and resolves/rejects with its result\n * (an observable is drained to its last value, same as the real\n * channel).\n * - `handle()` re-throws, so the next `.catch` in the chain still sees the\n * error.\n *\n * This lets call sites use `useStudioErrorHandler()` unconditionally\n * instead of branching on whether a Studio is present.\n *\n * @internal\n */\nexport const passthroughErrorHandler: StudioErrorHandler = {\n attempt(thunk) {\n return Promise.resolve(1).then((n) => {\n const result = thunk(n)\n return isObservable(result) ? lastValueFrom(result) : result\n })\n },\n handle(err) {\n return Promise.reject(err)\n },\n}\n","import {useContext} from 'react'\nimport {StudioErrorHandlerContext} from 'sanity/_singletons'\n\nimport {passthroughErrorHandler} from './createRequestErrorChannel'\nimport {type StudioErrorHandler} from './types'\n\n/**\n * Access the studio's request-error reporter — the call-site API for\n * delegating unrecoverable request errors (network failures, 5xx, 429)\n * to the studio's built-in error UI.\n *\n * The studio never intercepts requests on its own: plugins and\n * customizations handle their own errors by default (inline errors,\n * toasts, fallbacks). Use this reporter for the failures your code\n * cannot recover from locally.\n *\n * Always returns a handler, so call sites never have to branch on whether\n * a Studio is present. Outside a `WorkspacesProvider` (e.g. a standalone\n * render of a component that normally lives in a Studio) it returns a\n * passthrough handler with no dialog and no retry: `attempt()` just runs\n * the work, and `handle()` re-throws to the caller's own `.catch`.\n *\n * @example\n * ```tsx\n * function MyPluginComponent() {\n * const client = useClient({apiVersion: '2025-02-19'})\n * const {attempt, handle} = useStudioErrorHandler()\n *\n * const loadSettings = useCallback(async () => {\n * // Retryable read: \"Try again\" in the studio dialog re-runs the thunk.\n * const settings = await attempt(\n * () => client.fetch('*[_id == \"myPlugin.settings\"][0]'),\n * {retryable: true},\n * )\n * return settings\n * }, [client, attempt])\n *\n * const save = useCallback(\n * (doc: SanityDocument) =>\n * client\n * .createOrReplace(doc)\n * // Fire-and-surface: a network/5xx failure shows the studio\n * // dialog (reload-only, conservative copy). Caller-domain errors\n * // (validation, permissions) are re-thrown to the next .catch.\n * .catch(handle)\n * .catch(showInlineValidationError),\n * [client, handle],\n * )\n * // ...\n * }\n * ```\n *\n * @beta\n */\nexport function useStudioErrorHandler(): StudioErrorHandler {\n return useContext(StudioErrorHandlerContext) ?? passthroughErrorHandler\n}\n","import {useSource} from '../studio/source'\nimport {type Template} from '../templates/types'\n\n/**\n *\n * @hidden\n * @beta\n */\nexport function useTemplates(): Template[] {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n return useSource().templates\n}\n","/**\n * Maximum size in bytes for document IDs in a single query.\n * This matches the limit used in availability.ts and accounts for\n * the Sanity client's max query size with room for headers.\n */\nexport const MAX_DOCUMENT_ID_CHUNK_SIZE = 11164\n","import QuickLRU from 'quick-lru'\nimport {concat, defer, EMPTY, map, type Observable, of, type OperatorFunction} from 'rxjs'\nimport {tap} from 'rxjs/operators'\n\n/**\n * The interface that any caching layer must implement\n * @internal\n */\ninterface SWRCache<T> {\n /**\n * Note: This will throw if key does not exist. Always check for existence with `has` before calling\n */\n get(key: string): T\n has(key: string): boolean\n set(key: string, value: T): void\n delete(key: string): void\n}\n\nconst createSWRCache = createLRUCache\n\n/**\n *\n * Create an SWR (Stale While Revalidate) rxjs operator that will store the latest value in a cache and emit the last know value upon observable subscription\n * @param options - Options\n * @internal\n */\nexport function createSWR<T>(options: {maxSize: number}) {\n const cache = createSWRCache<T>(options)\n return function rxSwr(key: string): OperatorFunction<T, {fromCache: boolean; value: T}> {\n return (input$: Observable<T>) => {\n return concat(\n defer(() => (cache.has(key) ? of({fromCache: true, value: cache.get(key)}) : EMPTY)),\n input$.pipe(\n tap((result) => cache.set(key, result)),\n map((value) => ({\n fromCache: false,\n value: value,\n })),\n ),\n )\n }\n }\n}\n\n/**\n * For now, the only cache layer implemented is an in-memory LRU.\n * @param options - LRU options\n * @internal\n */\nfunction createLRUCache<T>(options: {maxSize: number}): SWRCache<T> {\n const lru = new QuickLRU<string, {value: T}>(options)\n return {\n get(key: string) {\n const entry = lru.get(key)\n if (!entry) {\n throw new Error(`Key not found in LRU cache: ${key}`)\n }\n return entry.value\n },\n set(key: string, value: T) {\n lru.set(key, {value})\n },\n delete(key: string) {\n lru.delete(key)\n },\n has(key: string) {\n return lru.has(key)\n },\n }\n}\n","/**\n * Shallow equality for plain objects and arrays, comparing entries with `===` one level deep.\n *\n * The object branch iterates with `for..in` instead of `Object.keys` on purpose: it avoids two\n * array allocations per call and benchmarks ~2x faster on the flat records this compares\n * (permission results, pane params, document top levels).\n *\n * @internal\n */\nexport function shallowEquals<T>(a: T, b: T): boolean {\n if (a === b) return true\n if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) return false\n const aIsArray = Array.isArray(a)\n if (aIsArray !== Array.isArray(b)) return false\n if (aIsArray) {\n const arrayA = a as unknown[]\n const arrayB = b as unknown[]\n if (arrayA.length !== arrayB.length) return false\n for (let index = 0; index < arrayA.length; index++) {\n if (arrayA[index] !== arrayB[index]) return false\n }\n return true\n }\n const recordA = a as Record<string, unknown>\n const recordB = b as Record<string, unknown>\n let countA = 0\n let countB = 0\n for (const key in recordA) {\n if (Object.prototype.hasOwnProperty.call(recordA, key)) {\n if (recordA[key] !== recordB[key]) return false\n countA++\n }\n }\n for (const key in recordB) {\n if (Object.prototype.hasOwnProperty.call(recordB, key)) countB++\n }\n return countA === countB\n}\n","import {WarningOutlineIcon} from '@sanity/icons/WarningOutline'\nimport {type PreviewValue} from '@sanity/types'\n\nexport const INCLUDE_FIELDS_QUERY = ['_id', '_rev', '_type']\nexport const INCLUDE_FIELDS = [...INCLUDE_FIELDS_QUERY, '_key']\n\n/**\n * How long to wait after the last subscriber has unsubscribed before resetting the observable and disconnecting the listener.\n * We want to keep the listener alive for a short while after the last subscriber has unsubscribed to avoid unnecessary reconnects.\n * Reduced from 10s to 5s to limit concurrent SSE connections during navigation-heavy sessions.\n */\nexport const LISTENER_RESET_DELAY = 5_000\n\nexport const AVAILABILITY_READABLE = {\n available: true,\n reason: 'READABLE',\n} as const\n\nexport const AVAILABILITY_PERMISSION_DENIED = {\n available: false,\n reason: 'PERMISSION_DENIED',\n} as const\n\nexport const AVAILABILITY_NOT_FOUND = {\n available: false,\n reason: 'NOT_FOUND',\n} as const\n\nexport const AVAILABILITY_VERSION_DELETED = {\n available: false,\n reason: 'VERSION_DELETED',\n} as const\n\nexport const INVALID_PREVIEW_FALLBACK: PreviewValue = {\n title: 'Invalid preview config',\n subtitle: 'Check the error log in the console',\n media: <WarningOutlineIcon />,\n}\n\n// oxlint-disable-next-line typescript/prefer-as-const\nexport const DOCUMENT_SYSTEM_FIELD: '_system' = '_system'\n","import {Observable, type Subscriber} from 'rxjs'\n\nimport {isNonNullable} from '../../util/isNonNullable'\n\ninterface QueueItem {\n args: any[]\n observer: Subscriber<any>\n completed: boolean\n}\n\n// Takes an observable returning function and returns a debounced function that, when called\n// collects its passed arguments until wait time has passed without receiving new calls.\n// When wait period is over, calls the original function with the collected arguments\nexport function debounceCollect<Fn extends (...args: any[]) => Observable<any[]>>(\n fn: Fn,\n wait: number,\n): Fn extends (collectedArgs: [...infer TArgs][]) => Observable<(infer TReturnValue)[]>\n ? (...args: TArgs) => Observable<TReturnValue>\n : never\nexport function debounceCollect(fn: any, wait: number) {\n let timer: ReturnType<typeof setTimeout>\n let queue: Record<number | string, QueueItem | undefined> = {}\n let idx = 0\n return function debounced(...args: any[]) {\n return new Observable((obs) => {\n clearTimeout(timer)\n timer = setTimeout(flush, wait)\n const queueItem: QueueItem = {\n args: args,\n observer: obs,\n completed: false,\n }\n const id = idx++\n queue[id] = queueItem\n return () => {\n // console.log('completed', queueItem.args)\n queueItem.completed = true\n }\n })\n }\n\n function flush() {\n const currentlyFlushingQueue = queue\n queue = {}\n\n const queueItemIds = Object.keys(currentlyFlushingQueue) // Todo: use debug\n // .map(id => {\n // if (currentlyFlushingQueue[id].completed) {\n // console.log('Dropped', currentlyFlushingQueue[id].args)\n // }\n // return id\n // })\n .filter((id) => {\n const queueItem = currentlyFlushingQueue[id]\n\n return queueItem && !queueItem.completed\n })\n\n if (queueItemIds.length === 0) {\n // nothing to do\n return\n }\n const collectedArgs = queueItemIds\n .map((id) => {\n const queueItem = currentlyFlushingQueue[id]\n\n return queueItem && queueItem.args\n })\n .filter(isNonNullable)\n fn(collectedArgs).subscribe({\n next(results: any[]) {\n results.forEach((result, i) => {\n const queueItem = currentlyFlushingQueue[queueItemIds[i]]\n if (queueItem && !queueItem.completed) {\n queueItem.observer.next(results[i])\n }\n })\n },\n complete() {\n queueItemIds.forEach((id) => {\n const entry = currentlyFlushingQueue[id]\n if (entry && !entry.completed) {\n entry.observer.complete()\n }\n })\n },\n error(err: Error) {\n queueItemIds.forEach((id) => {\n const entry = currentlyFlushingQueue[id]\n if (entry && !entry.completed) {\n entry.observer.error(err)\n }\n })\n },\n })\n }\n}\n","import {type SanityClient, type StackablePerspective} from '@sanity/client'\nimport flatten from 'lodash-es/flatten.js'\nimport keyBy from 'lodash-es/keyBy.js'\nimport {combineLatest, defer, from, type Observable, of} from 'rxjs'\nimport {distinctUntilChanged, map, mergeMap, reduce, switchMap} from 'rxjs/operators'\n\nimport {MAX_DOCUMENT_ID_CHUNK_SIZE} from '../util/const'\nimport {getDraftId, getPublishedId, getVersionId} from '../util/draftUtils'\nimport {isRecord} from '../util/isRecord'\nimport {createSWR} from '../util/rxSwr'\nimport {shallowEquals} from '../util/shallowEquals'\nimport {\n AVAILABILITY_NOT_FOUND,\n AVAILABILITY_PERMISSION_DENIED,\n AVAILABILITY_READABLE,\n AVAILABILITY_VERSION_DELETED,\n} from './constants'\nimport {\n type AvailabilityResponse,\n type DocumentAvailability,\n type DocumentStackAvailability,\n type DraftsModelDocumentAvailability,\n type ObservePathsFn,\n} from './types'\nimport {debounceCollect} from './utils/debounceCollect'\n/**\n * Create an SWR operator for document availability\n */\nconst swr = createSWR<DocumentAvailability>({maxSize: 1000})\n\n/**\n * Takes an array of document IDs and puts them into individual chunks.\n * Because document IDs can vary greatly in size, we want to chunk by the length of the\n * combined comma-separated ID set. We try to stay within 11164 bytes - this is about the\n * same length the Sanity client uses for max query size, and accounts for rather large\n * headers to be present - so this _should_ be safe.\n *\n * @param documentIds - Unique document IDs to chunk\n * @returns Array of document ID chunks\n */\nfunction chunkDocumentIds(documentIds: string[]): string[][] {\n let chunk: string[] = []\n let chunkSize = 0\n\n const chunks: string[][] = []\n\n for (const documentId of documentIds) {\n // Reached the max length? start a new chunk\n if (chunkSize + documentId.length + 1 >= MAX_DOCUMENT_ID_CHUNK_SIZE) {\n chunks.push(chunk)\n chunk = []\n chunkSize = 0\n }\n\n chunkSize += documentId.length + 1 // +1 is to account for a comma between IDs\n chunk.push(documentId)\n }\n\n if (!chunks.includes(chunk)) {\n chunks.push(chunk)\n }\n\n return chunks\n}\n\n/**\n * Mutative concat\n * @param array - the array to concat to\n * @param chunks - the items to concat to the array\n */\nfunction mutConcat<T>(array: T[], chunks: T[]) {\n array.push(...chunks)\n return array\n}\n\nfunction createDocumentAvailabilityObserver(\n versionedClient: SanityClient,\n observePaths: ObservePathsFn,\n): (id: string) => Observable<DocumentAvailability> {\n const fetchDocumentReadability = debounceCollect(function fetchDocumentReadability(\n args: string[][],\n ): Observable<DocumentAvailability[]> {\n const uniqueIds = [...new Set(flatten(args))]\n return from(chunkDocumentIds(uniqueIds)).pipe(\n mergeMap(fetchDocumentReadabilityChunked, 10),\n reduce<DocumentAvailability[], DocumentAvailability[]>(mutConcat, []),\n map((res) => args.map(([id]) => res[uniqueIds.indexOf(id)])),\n )\n }, 1)\n\n function fetchDocumentReadabilityChunked(ids: string[]): Observable<DocumentAvailability[]> {\n return defer(() => {\n const requestOptions = {\n url: versionedClient.getDataUrl('doc', ids.join(',')),\n json: true,\n query: {excludeContent: 'true'},\n tag: 'preview.documents-availability',\n }\n return versionedClient.observable.request<AvailabilityResponse>(requestOptions).pipe(\n map((response) => {\n const omitted = keyBy(response.omitted || [], (entry) => entry.id)\n return ids.map((id) => {\n const omittedEntry = omitted[id]\n if (!omittedEntry) {\n // it's not omitted, so it exists and is readable\n return AVAILABILITY_READABLE\n }\n if (omittedEntry.reason === 'existence') {\n return AVAILABILITY_NOT_FOUND\n }\n if (omittedEntry.reason === 'permission') {\n // it's not omitted, so it exists and is readable\n return AVAILABILITY_PERMISSION_DENIED\n }\n throw new Error(`Unexpected reason for omission: \"${omittedEntry.reason}\"`)\n })\n }),\n )\n })\n }\n\n /**\n * Observable of metadata for the document with the given id\n * If we can't read a document it is either because it's not readable or because it doesn't exist\n *\n * @internal\n */\n return function observeDocumentAvailability(id: string): Observable<DocumentAvailability> {\n // check for existence first, observePaths is lightweight\n return observePaths({_id: id}, [['_rev'], ['_system']]).pipe(\n map((res) => ({\n hasRev: isRecord(res) && Boolean('_rev' in res && res?._rev),\n isDeleted: isRecord(res) && res._system?.delete === true,\n })),\n distinctUntilChanged(),\n switchMap(({hasRev, isDeleted}) => {\n if (isDeleted) {\n return of(AVAILABILITY_VERSION_DELETED)\n }\n\n return hasRev\n ? // short circuit: if we can read the _rev field we know it both exists and is readable\n of(AVAILABILITY_READABLE)\n : // we can't read the _rev field for two possible reasons: 1) the document isn't readable or 2) the document doesn't exist\n fetchDocumentReadability(id)\n }),\n swr(id),\n map((ev) => ev.value),\n )\n }\n}\n\nfunction ensurePublished(stack: StackablePerspective[]) {\n return stack.includes('published') ? stack : stack.concat(['published'])\n}\n\nexport function createDocumentStackAvailabilityObserver(\n versionedClient: SanityClient,\n observePaths: ObservePathsFn,\n): (id: string, perspective: StackablePerspective[]) => Observable<DocumentStackAvailability[]> {\n const observeDocumentAvailability = createDocumentAvailabilityObserver(\n versionedClient,\n observePaths,\n )\n\n return (id: string, stack: StackablePerspective[]) => {\n return combineLatest(\n // explicitly check availability for published id (we're not using perspective in the following fetch here)\n ensurePublished(stack).map((perspective) => {\n const versionId =\n perspective === 'drafts'\n ? getDraftId(id)\n : perspective === 'published'\n ? getPublishedId(id)\n : getVersionId(id, perspective)\n return observeDocumentAvailability(versionId).pipe(\n map((availability) => ({availability, id: versionId})),\n )\n }),\n )\n }\n}\n\nexport function createPreviewAvailabilityObserver(\n versionedClient: SanityClient,\n observePaths: ObservePathsFn,\n): (id: string) => Observable<DraftsModelDocumentAvailability> {\n const observeDocumentAvailability = createDocumentAvailabilityObserver(\n versionedClient,\n observePaths,\n )\n /**\n * Returns an observable of metadata for a given drafts model document\n */\n return function observeDocumentPairAvailability(\n id: string,\n {version}: {version?: string} = {},\n ): Observable<DraftsModelDocumentAvailability> {\n const draftId = getDraftId(id)\n const publishedId = getPublishedId(id)\n const versionId = version ? getVersionId(id, version) : undefined\n return combineLatest([\n observeDocumentAvailability(draftId),\n observeDocumentAvailability(publishedId),\n ...(versionId ? [observeDocumentAvailability(versionId)] : []),\n ]).pipe(\n distinctUntilChanged(shallowEquals),\n map(([draftReadability, publishedReadability, versionReadability]) => {\n return {\n draft: draftReadability,\n published: publishedReadability,\n ...(versionReadability\n ? {\n version: versionReadability,\n }\n : {}),\n }\n }),\n )\n }\n}\n","import {\n finalize,\n merge,\n type MonoTypeOperatorFunction,\n Observable,\n share,\n type ShareConfig,\n tap,\n} from 'rxjs'\n\nexport type ShareReplayLatestConfig<T> = ShareConfig<T> & {predicate: (value: T) => boolean}\n\n/**\n * A variant of share that takes a predicate function to determine which value to replay to new subscribers\n * @param predicate - Predicate function to determine which value to replay\n */\nexport function shareReplayLatest<T>(predicate: (value: T) => boolean): MonoTypeOperatorFunction<T>\n\n/**\n * A variant of share that takes a predicate function to determine which value to replay to new subscribers\n * @param config - ShareConfig with additional predicate function\n */\nexport function shareReplayLatest<T>(\n config: ShareReplayLatestConfig<T>,\n): MonoTypeOperatorFunction<T>\n\n/**\n * A variant of share that takes a predicate function to determine which value to replay to new subscribers\n * @param configOrPredicate - Predicate function to determine which value to replay\n * @param config - Optional ShareConfig\n */\nexport function shareReplayLatest<T>(\n configOrPredicate: ShareReplayLatestConfig<T> | ShareReplayLatestConfig<T>['predicate'],\n config?: ShareConfig<T>,\n) {\n return _shareReplayLatest(\n typeof configOrPredicate === 'function'\n ? {predicate: configOrPredicate, ...config}\n : configOrPredicate,\n )\n}\nfunction _shareReplayLatest<T>(config: ShareReplayLatestConfig<T>): MonoTypeOperatorFunction<T> {\n return (source: Observable<T>) => {\n let latest: T | undefined\n let emitted = false\n\n const {predicate, ...shareConfig} = config\n\n const wrapped = source.pipe(\n tap((value) => {\n if (config.predicate(value)) {\n emitted = true\n latest = value\n }\n }),\n finalize(() => {\n emitted = false\n latest = undefined\n }),\n share(shareConfig),\n )\n const emitLatest = new Observable<T>((subscriber) => {\n if (emitted) {\n subscriber.next(\n // this cast is safe because of the emitted check which asserts that we got T from the source\n latest as T,\n )\n }\n subscriber.complete()\n })\n return merge(wrapped, emitLatest)\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {timer} from 'rxjs'\n\nimport {LISTENER_RESET_DELAY} from './constants'\nimport {shareReplayLatest} from './utils/shareReplayLatest'\n\n/**\n * @internal\n * Creates a listener that will emit 'welcome' for all new subscribers immediately, and thereafter emit at every mutation event\n */\nexport function createGlobalListener(client: SanityClient) {\n return client\n .listen(\n '*',\n {},\n {\n events: ['welcome', 'mutation', 'reconnect'],\n includeResult: false,\n includePreviousRevision: false,\n includeMutations: false,\n includeAllVersions: true,\n visibility: 'query',\n effectFormat: 'mendoza',\n tag: 'preview.global',\n },\n )\n .pipe(\n shareReplayLatest({\n predicate: (event) => event.type === 'welcome' || event.type === 'reconnect',\n resetOnRefCountZero: () => timer(LISTENER_RESET_DELAY),\n }),\n )\n}\n","import {type SanityDocument} from '@sanity/types'\nimport {applyPatch, type RawPatch} from 'mendoza'\n\nfunction omitRev(document: SanityDocument | undefined) {\n if (document === undefined) {\n return undefined\n }\n const {_rev, ...doc} = document\n return doc\n}\n\n/**\n *\n * @param document - The document to apply the patch to\n * @param patch - The mendoza patch to apply\n * @param baseRev - The revision of the document that the patch is calculated from. This is used to ensure that the patch is applied to the correct revision of the document\n */\nexport function applyMendozaPatch<T extends SanityDocument | undefined>(\n document: T,\n patch: RawPatch,\n baseRev: string,\n): T | undefined {\n if (baseRev !== document?._rev) {\n throw new Error(\n 'Invalid document revision. The provided patch is calculated from a different revision than the current document',\n )\n }\n const next = applyPatch(omitRev(document), patch)\n return next === null ? undefined : next\n}\n\nexport function applyMutationEventEffects(\n document: SanityDocument | undefined,\n event: {effects: {apply: RawPatch}; previousRev: string; resultRev: string},\n) {\n if (!event.effects) {\n throw new Error(\n 'Mutation event is missing effects. Is the listener set up with effectFormat=mendoza?',\n )\n }\n const next = applyMendozaPatch(document, event.effects.apply, event.previousRev)\n // next will be undefined in case of deletion\n return next ? {...next, _rev: event.resultRev} : undefined\n}\n","import {type MutationEvent, type SanityClient, type WelcomeEvent} from '@sanity/client'\nimport {type SanityDocument} from '@sanity/types'\nimport memoize from 'lodash-es/memoize.js'\nimport uniq from 'lodash-es/uniq.js'\nimport {type RawPatch} from 'mendoza'\nimport {EMPTY, finalize, type Observable, of} from 'rxjs'\nimport {concatMap, map, scan, shareReplay} from 'rxjs/operators'\n\nimport {applyMutationEventEffects} from './utils/applyMendozaPatch'\nimport {debounceCollect} from './utils/debounceCollect'\n\nexport type ListenerMutationEventLike = Pick<\n MutationEvent,\n 'type' | 'documentId' | 'previousRev' | 'resultRev'\n> & {\n effects?: {\n apply: unknown[]\n }\n}\nexport interface ObserveDocumentAPIConfig {\n dataset?: string\n projectId?: string\n apiVersion?: string\n}\n\nexport function createObserveDocument({\n mutationChannel,\n client,\n}: {\n client: SanityClient\n mutationChannel: Observable<WelcomeEvent | ListenerMutationEventLike>\n}) {\n const getBatchFetcher = memoize(\n function getBatchFetcher(apiConfig: {dataset: string; projectId: string; apiVersion: string}) {\n const _client = client.withConfig(apiConfig)\n\n function batchFetchDocuments(ids: [string][]) {\n return _client.observable\n .fetch(`*[_id in $ids]`, {ids: uniq(ids.flat())}, {tag: 'preview.observe-document'})\n .pipe(map((result) => ids.map(([id]) => result.find((r: {_id: string}) => r._id === id))))\n }\n return debounceCollect(batchFetchDocuments, 100)\n },\n (apiConfig) => apiConfig.dataset + apiConfig.projectId + apiConfig.apiVersion,\n )\n\n const MEMO: Record<string, Observable<SanityDocument | undefined>> = {}\n\n function observeDocument(id: string, apiConfig?: ObserveDocumentAPIConfig) {\n const _apiConfig = {\n dataset: apiConfig?.dataset || client.config().dataset!,\n projectId: apiConfig?.projectId || client.config().projectId!,\n apiVersion: apiConfig?.apiVersion || client.config().apiVersion,\n }\n const fetchDocument = getBatchFetcher(_apiConfig)\n return mutationChannel.pipe(\n concatMap((event) => {\n if (event.type === 'welcome') {\n return fetchDocument(id).pipe(map((document) => ({type: 'sync' as const, document})))\n }\n return event.documentId === id ? of(event) : EMPTY\n }),\n scan((current: SanityDocument | undefined, event) => {\n if (event.type === 'sync') {\n return event.document\n }\n if (event.type === 'mutation') {\n return applyMutationEvent(current, event)\n }\n //@ts-expect-error - this should never happen\n throw new Error(`Unexpected event type: \"${event.type}\"`)\n }, undefined),\n )\n }\n return function memoizedObserveDocument(id: string, apiConfig?: ObserveDocumentAPIConfig) {\n const key = apiConfig ? `${id}-${JSON.stringify(apiConfig)}` : id\n if (!(key in MEMO)) {\n MEMO[key] = observeDocument(id, apiConfig).pipe(\n finalize(() => delete MEMO[key]),\n shareReplay({bufferSize: 1, refCount: true}),\n )\n }\n return MEMO[key]\n }\n}\n\nfunction applyMutationEvent(current: SanityDocument | undefined, event: ListenerMutationEventLike) {\n if (event.previousRev !== current?._rev) {\n console.warn('Document out of sync, skipping mutation')\n return current\n }\n if (!event.effects) {\n throw new Error(\n 'Mutation event is missing effects. Is the listener set up with effectFormat=mendoza?',\n )\n }\n return applyMutationEventEffects(\n current,\n event as {effects: {apply: RawPatch}; previousRev: string; resultRev: string},\n )\n}\n","export function keysOf<T extends object>(value: T) {\n return Object.keys(value) as (keyof T)[]\n}\n","import {\n combineLatest,\n from as observableFrom,\n isObservable,\n Observable,\n of as observableOf,\n} from 'rxjs'\nimport {map, mergeAll, scan, switchMap} from 'rxjs/operators'\n\nimport {keysOf} from './keysOf'\n\nfunction setKey(source: Record<string, unknown>, key: any, value: unknown) {\n return {\n ...source,\n [key]: value,\n }\n}\n\ntype Props<K extends keyof any, T> = {\n [P in K]: T | Observable<T>\n}\n\nexport function props<K extends keyof any, T>(options: {wait?: boolean} = {}) {\n return (source: Observable<Props<K, T>>) => {\n return new Observable<Props<K, T>>((observer) => source.subscribe(observer)).pipe(\n switchMap((object) => {\n const keyObservables = keysOf(object).map((key) => {\n const value = object[key]\n return isObservable(value)\n ? observableFrom(value).pipe(map((val) => [key, val]))\n : observableOf([key, value])\n })\n\n return options.wait\n ? combineLatest(keyObservables).pipe(\n map((pairs) => pairs.reduce((acc, [key, value]) => setKey(acc, key, value), {})),\n )\n : observableFrom(keyObservables).pipe(\n mergeAll(),\n scan((acc, [key, value]) => setKey(acc, key, value), {}),\n )\n }),\n )\n }\n}\n","import {type StackablePerspective} from '@sanity/client'\nimport {isCrossDatasetReference, isReference} from '@sanity/types'\nimport uniq from 'lodash-es/uniq.js'\nimport {type Observable, of as observableOf} from 'rxjs'\nimport {distinctUntilChanged, switchMap} from 'rxjs/operators'\n\nimport {isRecord} from '../util/isRecord'\nimport {type ApiConfig, type FieldName, type Previewable, type PreviewPath} from './types'\nimport {props} from './utils/props'\n\nfunction createEmpty(fields: FieldName[]) {\n return fields.reduce((result: Record<string, undefined>, field) => {\n result[field] = undefined\n return result\n }, {})\n}\n\nfunction resolveMissingHeads(value: Record<string, unknown>, paths: string[][]) {\n return paths.filter((path) => !(path[0] in value))\n}\n\nfunction getDocumentId(value: Previewable) {\n if (isReference(value)) {\n return value._ref\n }\n return '_id' in value ? value._id : undefined\n}\n\ntype ObserveFieldsFn = (\n id: string,\n fields: FieldName[],\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n) => Observable<Record<string, unknown> | null>\n\nfunction observePaths(\n value: Previewable,\n paths: PreviewPath[],\n observeFields: ObserveFieldsFn,\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n): Observable<Record<string, unknown> | null> {\n if (!value || typeof value !== 'object') {\n // Reached a leaf. Return as is\n return observableOf(value as null) // @todo\n }\n\n const id = getDocumentId(value)\n\n const currentValue: Record<string, unknown> = id ? {...value, _id: id} : {...value}\n\n if (currentValue._type === 'reference') {\n delete currentValue._type\n delete currentValue._ref\n delete currentValue._weak\n delete currentValue._dataset\n delete currentValue._projectId\n delete currentValue._strengthenOnPublish\n }\n\n const pathsWithMissingHeads = resolveMissingHeads(currentValue, paths)\n\n if (id && pathsWithMissingHeads.length > 0) {\n // Reached a node that is either a document (with _id), or a reference (with _ref) that\n // needs to be \"materialized\"\n\n const nextHeads: string[] = uniq(pathsWithMissingHeads.map((path: string[]) => path[0]))\n\n const refApiConfig = isCrossDatasetReference(value)\n ? {projectId: value._projectId, dataset: value._dataset}\n : apiConfig\n\n return observeFields(id, nextHeads, refApiConfig, perspective, variant).pipe(\n distinctUntilChanged((prev, curr) => prev?._rev === curr?._rev),\n switchMap((snapshot) => {\n if (snapshot === null) {\n return observableOf(null)\n }\n\n return observePaths(\n {\n ...createEmpty(nextHeads),\n ...(isReference(value) ? {...value, ...refApiConfig} : value),\n ...snapshot,\n } as Previewable,\n paths,\n observeFields,\n refApiConfig,\n perspective,\n variant,\n )\n }),\n )\n }\n\n // We have all the fields needed already present on value\n const leads: Record<string, string[][]> = {}\n paths.forEach((path) => {\n const [head, ...tail] = path\n if (!leads[head]) {\n leads[head] = []\n }\n leads[head].push(tail)\n })\n\n const next = Object.keys(leads).reduce((res: Record<string, unknown>, head) => {\n const tails = leads[head].filter((tail) => tail.length > 0)\n if (tails.length === 0) {\n res[head] =\n isRecord(value) || Array.isArray(value)\n ? (value as Record<string, unknown>)[head]\n : undefined\n } else {\n res[head] = observePaths(\n (value as any)[head],\n tails,\n observeFields,\n apiConfig,\n perspective,\n variant,\n )\n }\n return res\n }, currentValue)\n\n return observableOf(next).pipe(props({wait: true}))\n}\n\n// Normalizes path arguments so it supports both dot-paths and array paths, e.g.\n// - ['propA.propB', 'propA.propC']\n// - [['propA', 'propB'], ['propA', 'propC']]\nfunction normalizePaths(path: (FieldName | PreviewPath)[]): PreviewPath[] {\n return path.map((segment: FieldName | PreviewPath) =>\n typeof segment === 'string' ? segment.split('.') : segment,\n )\n}\n\n/**\n * Creates a function that allows observing nested paths on a document.\n * If the path includes a reference, the reference will be \"followed\", allowing for selecting paths within the referenced document.\n * @param options - Requires a function that can observe fields on a document\n * @internal\n */\nexport function createPathObserver(options: {observeFields: ObserveFieldsFn}) {\n const {observeFields} = options\n\n return (\n value: Previewable,\n paths: (FieldName | PreviewPath)[],\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ): Observable<Record<string, unknown> | null> => {\n return observePaths(\n value,\n normalizePaths(paths),\n observeFields,\n apiConfig,\n perspective,\n variant,\n )\n }\n}\n","import {type PreviewableType, type PreviewPath} from '../types'\n\nconst DEFAULT_PREVIEW_PATHS: PreviewPath[] = [['_createdAt'], ['_updatedAt']]\n\n/** @internal */\nexport function getPreviewPaths(preview: PreviewableType['preview']): PreviewPath[] | undefined {\n const selection = preview?.select\n\n if (!selection) return undefined\n\n // Transform the selection dot-notation paths into array paths.\n // Example: ['object.title', 'name'] => [['object', 'title'], ['name']]\n const paths = Object.values(selection).map((value) => String(value).split('.')) || []\n\n // Return the paths with the default preview paths appended.\n return paths.concat(DEFAULT_PREVIEW_PATHS)\n}\n","import {isPortableTextSpan, isPortableTextTextBlock, type PortableTextBlock} from '@sanity/types'\n\nexport function isPortableTextPreviewValue(value: unknown): value is PortableTextBlock[] {\n return Array.isArray(value) && (value.length === 0 || value.some(isPortableTextTextBlock))\n}\n\nexport function extractTextFromBlocks(blocks: unknown): string {\n const firstBlock = Array.isArray(blocks) && blocks.find(isPortableTextTextBlock)\n if (!firstBlock || !firstBlock.children) {\n return ''\n }\n\n return firstBlock.children\n .filter(isPortableTextSpan)\n .map((span) => span.text)\n .join('')\n}\n","import {\n isTitledListValue,\n type PrepareViewOptions,\n type PreviewValue,\n type SchemaType,\n type TitledListValue,\n} from '@sanity/types'\nimport debounce from 'lodash-es/debounce.js'\nimport flatten from 'lodash-es/flatten.js'\nimport get from 'lodash-es/get.js'\nimport isPlainObject from 'lodash-es/isPlainObject.js'\nimport pick from 'lodash-es/pick.js'\nimport uniqBy from 'lodash-es/uniqBy.js'\n\nimport {isRecord} from '../../util/isRecord'\nimport {INVALID_PREVIEW_FALLBACK} from '../constants'\nimport {type PreviewableType} from '../types'\nimport {keysOf} from './keysOf'\nimport {extractTextFromBlocks, isPortableTextPreviewValue} from './portableText'\n\nconst PRESERVE_KEYS = ['_id', '_type', '_upload', '_createdAt', '_updatedAt']\nconst EMPTY: never[] = []\n\ntype SelectedValue = Record<string, unknown>\n\nexport type PrepareInvocationResult = {\n selectedValue?: SelectedValue\n returnValue: null | PreviewValue\n errors: Error[]\n}\n\nconst errorCollector = (() => {\n let errorsByType: Record<string, {error: Error; type: PreviewableType; value: SelectedValue}[]> =\n {}\n\n return {\n add: (type: PreviewableType, value: SelectedValue, error: Error) => {\n // cross dataset referenced types have a `type` (string) property instead of `name`\n const typeName = 'name' in type ? type.name : type.type\n if (!errorsByType[typeName]) {\n errorsByType[typeName] = []\n }\n errorsByType[typeName].push({error: error, type: type, value})\n },\n getAll() {\n return errorsByType\n },\n clear() {\n errorsByType = {}\n },\n }\n})()\n\nconst reportErrors = debounce(() => {\n // oxlint-disable no-console\n const errorsByType = errorCollector.getAll()\n const uniqueErrors = flatten(\n Object.keys(errorsByType).map((typeName) => {\n const entries = errorsByType[typeName]\n return uniqBy(entries, (entry) => entry.error.message)\n }),\n )\n const errorCount = uniqueErrors.length\n if (errorCount === 0) {\n return\n }\n\n console.groupCollapsed(\n `%cHeads up! Got ${\n errorCount === 1 ? 'error' : `${errorCount} errors`\n } while preparing data for preview. Click for details.`,\n 'color: #ff7e7c',\n )\n\n Object.keys(errorsByType).forEach((typeName) => {\n const entries = errorsByType[typeName]\n const first = entries[0]\n console.group(`Check the preview config for schema type \"${typeName}\": %o`, first.type.preview)\n const uniqued = uniqBy(entries, (entry) => entry.error.message)\n uniqued.forEach((entry) => {\n if ((entry.error as any).type === 'returnValueError') {\n const hasPrepare = typeof entry.type.preview?.prepare === 'function'\n const {value, error} = entry\n console.log(\n `Encountered an invalid ${\n hasPrepare\n ? 'return value when calling prepare(%o)'\n : 'value targeted by preview.select'\n }:`,\n value,\n )\n console.error(error)\n }\n if ((entry.error as any).type === 'prepareError') {\n const {value, error} = entry\n console.log('Encountered an error when calling prepare(%o):', value)\n console.error(error)\n }\n })\n console.groupEnd()\n })\n console.groupEnd()\n errorCollector.clear()\n // oxlint-enable no-console\n}, 1000)\n\nconst isRenderable =\n (fieldName: string) =>\n (value: unknown): Error[] => {\n const type = typeof value\n if (\n value === null ||\n type === 'undefined' ||\n type === 'string' ||\n type === 'number' ||\n type === 'boolean'\n ) {\n return EMPTY\n }\n return [\n assignType(\n 'returnValueError',\n new Error(\n `The \"${fieldName}\" field should be a string, number, boolean, undefined or null, instead saw ${inspect(\n value,\n )}`,\n ),\n ),\n ]\n }\nconst FIELD_NAME_VALIDATORS: Record<string, (value: unknown) => Error[]> = {\n media: () => {\n // not sure how to validate media as it would possibly involve executing a function and check the\n // return value\n return EMPTY\n },\n title: isRenderable('title'),\n subtitle: isRenderable('subtitle'),\n description: isRenderable('description'),\n imageUrl: isRenderable('imageUrl'),\n date: isRenderable('date'),\n}\n\nfunction inspect(val: unknown, prefixType = true): string {\n if (isRecord(val)) {\n const keys = Object.keys(val)\n const ellipse = keys.length > 3 ? '...' : ''\n const prefix = `object with keys `\n return `${prefixType ? prefix : ''}{${keys.slice(0, 3).join(', ')}${ellipse}}`\n }\n if (Array.isArray(val)) {\n const ellipse = val.length > 3 ? '...' : ''\n const prefix = `array with `\n return `${prefixType ? prefix : ''}[${val.map((v) => inspect(v, false))}${ellipse}]`\n }\n return `the ${typeof val} ${val}`\n}\n\nfunction validateFieldValue(fieldName: string, fieldValue: unknown) {\n if (typeof fieldValue === 'undefined') {\n return EMPTY\n }\n const validator = FIELD_NAME_VALIDATORS[fieldName]\n return (validator && validator(fieldValue)) || EMPTY\n}\n\nfunction assignType(type: string, error: Error) {\n return Object.assign(error, {type})\n}\n\nfunction validatePreparedValue(preparedValue: PreviewValue | null) {\n if (!isPlainObject(preparedValue) || preparedValue === null) {\n return [\n assignType(\n 'returnValueError',\n new Error(\n `Invalid return value. Expected a plain object with at least a 'title' field, instead saw ${inspect(\n preparedValue,\n )}`,\n ),\n ),\n ]\n }\n\n return Object.entries(preparedValue).reduce<Error[]>((acc, [fieldName, fieldValue]) => {\n return [...acc, ...validateFieldValue(fieldName, fieldValue)]\n }, EMPTY)\n}\n\nfunction validateReturnedPreview(result: PrepareInvocationResult) {\n return {\n ...result,\n errors: [...(result.errors || []), ...validatePreparedValue(result.returnValue)],\n }\n}\n\nfunction defaultPrepare(value: SelectedValue) {\n return keysOf(value).reduce((acc: SelectedValue, fieldName: keyof SelectedValue) => {\n const val = value[fieldName]\n return {\n ...acc,\n [fieldName]: isPortableTextPreviewValue(val) ? extractTextFromBlocks(val) : val,\n }\n }, {})\n}\n\nexport function invokePrepare(\n type: PreviewableType,\n value: SelectedValue,\n viewOptions: PrepareViewOptions = {},\n): PrepareInvocationResult {\n const prepare = type.preview?.prepare\n try {\n return {\n returnValue: prepare\n ? (prepare(value, viewOptions) as Record<string, unknown>)\n : defaultPrepare(value),\n errors: EMPTY,\n }\n } catch (error) {\n return {\n returnValue: null,\n errors: [assignType('prepareError', error)],\n }\n }\n}\n\nfunction withErrors(\n result: {errors: Error[]},\n type: PreviewableType,\n selectedValue: SelectedValue,\n): PreviewValue {\n result.errors.forEach((error) => errorCollector.add(type, selectedValue, error))\n reportErrors()\n\n return INVALID_PREVIEW_FALLBACK\n}\n\ninterface EnumListOptions {\n list: TitledListValue[] | unknown[]\n}\n\nfunction hasEnumListOptions(\n type: SchemaType,\n): type is SchemaType & {options: SchemaType['options'] & EnumListOptions} {\n const options = type.options && typeof type.options === 'object' ? type.options : false\n if (!options || !('list' in options)) {\n return false\n }\n\n const listOptions = (options as EnumListOptions).list\n return Array.isArray(listOptions)\n}\n\nfunction getListOptions(type: SchemaType): TitledListValue[] | undefined {\n if (!hasEnumListOptions(type)) {\n return undefined\n }\n\n const listOptions = type.options.list as EnumListOptions['list']\n return listOptions.map((option) =>\n isTitledListValue(option) ? option : ({title: option, value: option} as TitledListValue),\n )\n}\n\n/** @internal */\nexport function prepareForPreview(\n rawValue: unknown,\n type: PreviewableType,\n viewOptions: PrepareViewOptions = {},\n): PreviewValue & {_createdAt?: string; _updatedAt?: string} {\n const hasCustomPrepare = typeof type.preview?.prepare === 'function'\n const selection: Record<string, string> = type.preview?.select || {}\n const targetKeys = Object.keys(selection)\n\n const selectedValue = targetKeys.reduce<Record<string, unknown>>((acc, key) => {\n // Find the field the value belongs to\n const typeWithFields = 'fields' in type ? type : null\n const targetFieldName = selection[key]\n const valueField = typeWithFields?.fields?.find((f) => f.name === targetFieldName)\n const listOptions = valueField && getListOptions(valueField.type)\n\n // If the user has _not_ specified a `prepare()` function for the preview, and the\n // field type has an `options.list`, we want to use the title of the selected item\n // as the preview value. If, however, there _is_ a custom `prepare()`, we leave this\n // mapping up to the user to perform should they want to. This is both to maintain\n // backwards compatiblity, but also to allow using the raw value for prepare operations\n if (!hasCustomPrepare && listOptions) {\n // Find the selected option that matches the raw value\n const selectedOption =\n listOptions && listOptions.find((opt) => opt.value === get(rawValue, selection[key]))\n acc[key] = selectedOption ? selectedOption.value : get(rawValue, selection[key])\n } else {\n acc[key] = get(rawValue, selection[key])\n }\n\n return acc\n }, {})\n\n const prepareResult = invokePrepare(type, selectedValue, viewOptions)\n if (prepareResult.errors.length > 0) {\n return withErrors(prepareResult, type, selectedValue)\n }\n\n const returnValueResult = validateReturnedPreview(prepareResult)\n return returnValueResult.errors.length > 0\n ? withErrors(returnValueResult, type, selectedValue)\n : {...pick(rawValue, PRESERVE_KEYS), ...prepareResult.returnValue}\n}\n","import {type StackablePerspective} from '@sanity/client'\nimport {\n isCrossDatasetReference,\n isCrossDatasetReferenceSchemaType,\n isReferenceSchemaType,\n type PrepareViewOptions,\n} from '@sanity/types'\nimport isPlainObject from 'lodash-es/isPlainObject.js'\nimport {type Observable, of} from 'rxjs'\nimport {map, switchMap} from 'rxjs/operators'\n\nimport {type ObserveForPreviewFn} from './documentPreviewStore'\nimport {\n type ApiConfig,\n type ObserveDocumentTypeFromIdFn,\n type ObservePathsFn,\n type PreparedSnapshot,\n type Previewable,\n type PreviewableType,\n} from './types'\nimport {getPreviewPaths} from './utils/getPreviewPaths'\nimport {invokePrepare, prepareForPreview} from './utils/prepareForPreview'\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return isPlainObject(value)\n}\n\nfunction isReference(value: unknown): value is {_ref: string} {\n return isPlainObject(value)\n}\n\n/**\n * Takes a value and its type and prepares a snapshot for it that can be passed to a preview component\n * @internal\n */\nexport function createPreviewObserver(context: {\n observeDocumentTypeFromId: ObserveDocumentTypeFromIdFn\n observePaths: ObservePathsFn\n}): ObserveForPreviewFn {\n const {observeDocumentTypeFromId, observePaths} = context\n\n return function observeForPreview(\n value: Previewable,\n type: PreviewableType,\n options: {\n viewOptions?: PrepareViewOptions\n apiConfig?: ApiConfig\n perspective?: StackablePerspective[]\n variant?: string\n } = {},\n ): Observable<PreparedSnapshot> {\n const {viewOptions = {}, apiConfig, perspective, variant} = options\n if (isCrossDatasetReferenceSchemaType(type)) {\n // if the value is of type crossDatasetReference, but has no _ref property, we cannot prepare any value for the preview\n // and the most appropriate thing to do is to return `undefined` for snapshot\n if (!isCrossDatasetReference(value)) {\n return of({snapshot: undefined})\n }\n\n const refApiConfig = {projectId: value._projectId, dataset: value._dataset}\n\n return observeDocumentTypeFromId(value._ref, refApiConfig, perspective, variant).pipe(\n switchMap((typeName) => {\n if (typeName) {\n const refType = type.to.find((toType) => toType.type === typeName)\n if (refType) {\n return observeForPreview(value, refType, {\n apiConfig: refApiConfig,\n viewOptions,\n perspective,\n variant,\n })\n }\n }\n return of({snapshot: undefined})\n }),\n )\n }\n if (isReferenceSchemaType(type)) {\n // if the value is of type reference, but has no _ref property, we cannot prepare any value for the preview\n // and the most appropriate thing to do is to return `undefined` for snapshot\n if (!isReference(value)) {\n return of({snapshot: undefined})\n }\n // Previewing references actually means getting the referenced value,\n // and preview using the preview config of its type\n // We do this since there's no way of knowing the type of the referenced value by looking at the reference value alone\n return observeDocumentTypeFromId(value._ref, undefined, perspective, variant).pipe(\n switchMap((typeName) => {\n if (typeName) {\n const refType = type.to.find((toType) => toType.name === typeName)\n if (refType) {\n return observeForPreview(value, refType, {perspective, variant})\n }\n }\n // todo: in case we can't read the document type, we can figure out the reason why e.g. whether it's because\n // the document doesn't exist or it's not readable due to lack of permission.\n // We can use the \"observeDocumentAvailability\" function\n // for this, but currently not sure if needed\n return of({snapshot: undefined})\n }),\n )\n }\n const paths = getPreviewPaths(type.preview)\n if (paths) {\n return observePaths(value, paths, apiConfig, perspective, variant).pipe(\n map((snapshot) => ({\n type: type,\n snapshot: snapshot ? prepareForPreview(snapshot, type, viewOptions) : null,\n })),\n )\n }\n\n // Note: this case is typically rare (or non-existent) and occurs only if\n // the SchemaType doesn't have a `select` field. The schema compiler\n // provides a default `preview` implementation for `object`s, `image`s,\n // `file`s, and `document`s\n return of({\n type,\n snapshot:\n value && isRecord(value) ? invokePrepare(type, value, viewOptions).returnValue : null,\n })\n }\n}\n","import {type SanityDocument} from '@sanity/types'\nimport {combineLatest, type Observable, of} from 'rxjs'\nimport {map, switchMap} from 'rxjs/operators'\n\nimport {getIdPair} from '../util/draftUtils'\nimport {isRecord} from '../util/isRecord'\nimport {\n type DraftsModelDocument,\n type ObserveDocumentAvailabilityFn,\n type ObservePathsFn,\n type PreviewPath,\n} from './types'\n\nexport function createObservePathsDocumentPair(options: {\n observeDocumentPairAvailability: ObserveDocumentAvailabilityFn\n observePaths: ObservePathsFn\n}): <T extends SanityDocument = SanityDocument>(\n id: string,\n paths: PreviewPath[],\n) => Observable<DraftsModelDocument<T>> {\n const {observeDocumentPairAvailability, observePaths} = options\n\n const ALWAYS_INCLUDED_SNAPSHOT_PATHS: PreviewPath[] = [['_updatedAt'], ['_createdAt'], ['_type']]\n\n return function observePathsDocumentPair<T extends SanityDocument = SanityDocument>(\n id: string,\n paths: PreviewPath[],\n {version}: {version?: string} = {},\n ): Observable<DraftsModelDocument<T>> {\n const {draftId, publishedId, versionId} = getIdPair(id, {version})\n\n return observeDocumentPairAvailability(draftId, {version}).pipe(\n switchMap((availability) => {\n if (\n !availability.draft.available &&\n !availability.published.available &&\n !availability.version?.available\n ) {\n // short circuit, neither draft nor published is available so no point in trying to get a snapshot\n return of({\n id: publishedId,\n type: null,\n draft: {\n availability: availability.draft,\n snapshot: undefined,\n },\n published: {\n availability: availability.published,\n snapshot: undefined,\n },\n ...(availability.version\n ? {\n version: {\n availability: availability.version,\n snapshot: undefined,\n },\n }\n : {}),\n })\n }\n\n const snapshotPaths = [...paths, ...ALWAYS_INCLUDED_SNAPSHOT_PATHS]\n\n return combineLatest([\n observePaths({_type: 'reference', _ref: draftId}, snapshotPaths),\n observePaths({_type: 'reference', _ref: publishedId}, snapshotPaths),\n ...(version ? [observePaths({_type: 'reference', _ref: versionId}, snapshotPaths)] : []),\n ]).pipe(\n map(([draftSnapshot, publishedSnapshot, versionSnapshot]) => {\n // note: assume type is always the same\n const type =\n (isRecord(versionSnapshot) && '_type' in versionSnapshot && versionSnapshot._type) ||\n (isRecord(draftSnapshot) && '_type' in draftSnapshot && draftSnapshot._type) ||\n (isRecord(publishedSnapshot) &&\n '_type' in publishedSnapshot &&\n publishedSnapshot._type) ||\n null\n\n return {\n id: publishedId,\n type: typeof type === 'string' ? type : null,\n draft: {\n availability: availability.draft,\n snapshot: draftSnapshot as T,\n },\n published: {\n availability: availability.published,\n snapshot: publishedSnapshot as T,\n },\n ...(availability.version\n ? {\n version: {\n availability: availability.version,\n snapshot: versionSnapshot as T,\n },\n }\n : {}),\n }\n }),\n )\n }),\n )\n }\n}\n","import {type QueryParams, type SanityClient} from '@sanity/client'\nimport sortedIndex from 'lodash-es/sortedIndex.js'\nimport {of} from 'rxjs'\nimport {distinctUntilChanged, filter, map, mergeMap, scan, tap} from 'rxjs/operators'\n\nimport {type SourceClientOptions} from '../config/types'\nimport {versionedClient} from '../studioClient'\n\nexport type DocumentIdSetObserverState = {\n status: 'reconnecting' | 'connected'\n documentIds: string[]\n}\n\ninterface LiveDocumentIdSetOptions {\n insert?: 'sorted' | 'prepend' | 'append'\n apiVersion?: SourceClientOptions['apiVersion']\n}\n\nexport function createDocumentIdSetObserver(client: SanityClient) {\n return function observe(\n queryFilter: string,\n params?: QueryParams,\n options: LiveDocumentIdSetOptions = {},\n ) {\n const {insert: insertOption = 'sorted', apiVersion} = options\n\n const query = `*[${queryFilter}]._id`\n function fetchFilter() {\n return versionedClient(client, apiVersion)\n .observable.fetch(query, params, {\n tag: 'preview.observe-document-set.fetch',\n })\n .pipe(\n tap((result) => {\n if (!Array.isArray(result)) {\n throw new Error(\n `Expected query to return array of documents, but got ${typeof result}`,\n )\n }\n }),\n )\n }\n return versionedClient(client, apiVersion)\n .observable.listen(`*[${queryFilter}]`, params, {\n visibility: 'transaction',\n events: ['welcome', 'mutation', 'reconnect'],\n includeResult: false,\n includeMutations: false,\n includeAllVersions: true,\n tag: 'preview.observe-document-set.listen',\n })\n .pipe(\n mergeMap((event) => {\n return event.type === 'welcome'\n ? fetchFilter().pipe(map((result) => ({type: 'fetch' as const, result})))\n : of(event)\n }),\n scan(\n (\n state: DocumentIdSetObserverState | undefined,\n event,\n ): DocumentIdSetObserverState | undefined => {\n if (event.type === 'reconnect') {\n return {\n documentIds: state?.documentIds || [],\n ...state,\n status: 'reconnecting' as const,\n }\n }\n if (event.type === 'fetch') {\n return {...state, status: 'connected' as const, documentIds: event.result}\n }\n if (event.type === 'mutation') {\n if (event.transition === 'update') {\n // ignore updates, as we're only interested in documents appearing and disappearing from the set\n return state\n }\n if (event.transition === 'appear') {\n return {\n status: 'connected',\n documentIds: insert(state?.documentIds || [], event.documentId, insertOption),\n }\n }\n if (event.transition === 'disappear') {\n return {\n status: 'connected',\n documentIds: state?.documentIds\n ? state.documentIds.filter((id) => id !== event.documentId)\n : [],\n }\n }\n }\n return state\n },\n undefined,\n ),\n distinctUntilChanged(),\n filter(\n (state: DocumentIdSetObserverState | undefined): state is DocumentIdSetObserverState =>\n state !== undefined,\n ),\n )\n }\n}\n\nfunction insert<T>(array: T[], element: T, strategy: 'sorted' | 'prepend' | 'append') {\n let index\n if (strategy === 'prepend') {\n index = 0\n } else if (strategy === 'append') {\n index = array.length\n } else {\n index = sortedIndex(array, element)\n }\n\n return array.toSpliced(index, 0, element)\n}\n","import {type ClientPerspective} from '@sanity/client'\n\nimport {type SourceClientOptions} from '../../config/types'\n\n/**\n * @internal This is the client options used for the releases studio client, using the `X` API version for now\n * Will change to a specific version soon.\n * TODO: Remove after API version is stable and support releases\n */\nexport const RELEASES_STUDIO_CLIENT_OPTIONS: SourceClientOptions = {\n apiVersion: 'v2025-02-19',\n}\n\n/**\n * @internal Checks if the perspective is a release perspective\n * TODO: Remove after API version is stable and support releases\n */\nexport const isReleasePerspective = (\n perspective: ClientPerspective | undefined | string | string[],\n): boolean => {\n if (Array.isArray(perspective)) {\n return true\n }\n return false\n}\n","import {VARIANTS_STUDIO_CLIENT_OPTIONS} from '../store/constants'\n\n/**\n * Resolves the API version to use for a query that may carry a `variant` option.\n *\n * Fetching with a variant is only supported on the variants API version, which takes precedence\n * over any other version the caller would otherwise use (e.g. the releases version for stacked\n * perspectives).\n *\n * Intended to be used with `versionedClient`:\n *\n * ```ts\n * versionedClient(client, variantApiVersion(variant, releaseApiVersion))\n * ```\n *\n * @internal\n */\nexport function variantApiVersion(\n variant: string | undefined,\n fallbackApiVersion?: string,\n): string | undefined {\n return variant ? VARIANTS_STUDIO_CLIENT_OPTIONS.apiVersion : fallbackApiVersion\n}\n","export function hasEqualFields(fields: string[]) {\n return (object: Record<string, any> | null, otherObject: Record<string, any> | null) => {\n if (object === otherObject) {\n return true\n }\n if (!object || !otherObject) {\n return false\n }\n if (typeof object !== 'object' || typeof otherObject !== 'object') {\n return false\n }\n return fields.every((field) => object[field] === otherObject[field])\n }\n}\n","const id = <T>(value: T): T => value\n\ntype ItemSelector<T> = (element: T) => any\n\n// Takes an array and checks if each item is unique,\n// optionally by specifying an itemSelector function that will be called with\n// each item, returning the value to compare for uniqueness\nexport function isUniqueBy<T>(array: Array<T>, itemSelector: ItemSelector<T> = id): boolean {\n let prevItem\n let currItem\n for (let i = 0; i < array.length; i++) {\n if (i === 0) {\n prevItem = itemSelector(array[i])\n continue\n }\n currItem = itemSelector(array[i])\n if (prevItem !== currItem) {\n return false\n }\n prevItem = currItem\n }\n return true\n}\n","type SearchPathSegment = string | number | []\n\nconst GROQ_KEYWORDS = ['match', 'in', 'asc', 'desc', 'true', 'false', 'null']\nconst VALID_FIELD = /^[a-zA-Z_][a-zA-Z0-9_]*$/\n\n/** @internal */\nexport const fieldNeedsEscape = (fieldName: string): boolean =>\n !VALID_FIELD.test(fieldName) || GROQ_KEYWORDS.includes(fieldName)\n\n/** @internal */\nexport const escapeField = (fieldName: string): string => `[\"${fieldName}\"]`\n\nconst escapeFirst = (fieldName: string): string => `@${escapeField(fieldName)}`\n\nconst isEmptyArray = (value: unknown): value is [] => Array.isArray(value) && value.length === 0\n\n/** @internal */\nexport const joinPath = (pathArray: SearchPathSegment[]): string => {\n let path = ''\n for (let i = 0; i < pathArray.length; i++) {\n const pathSegment = pathArray[i]\n if (isEmptyArray(pathSegment)) {\n path += `[]`\n continue\n }\n\n if (typeof pathSegment === 'number') {\n path += `[${pathSegment}]`\n continue\n }\n\n const isFirst = i === 0\n const needsEscape = fieldNeedsEscape(pathSegment)\n\n if (needsEscape) {\n path = isFirst ? escapeFirst(pathSegment) : `${path}${escapeField(pathSegment)}`\n } else {\n path = isFirst ? pathSegment : `${path}.${pathSegment}`\n }\n }\n\n return path\n}\n","import identity from 'lodash-es/identity.js'\nimport sortBy from 'lodash-es/sortBy.js'\nimport values from 'lodash-es/values.js'\n\nimport {escapeField, fieldNeedsEscape} from '../../util/searchUtils'\nimport {INCLUDE_FIELDS_QUERY} from '../constants'\nimport {type FieldName, type Id, type Selection} from '../types'\n\n/** @internal */\nexport type CombinedSelection = {\n ids: Id[]\n fields: FieldName[]\n map: number[]\n}\n\ntype Doc = {\n _id: string\n}\n\ntype Result = Doc[]\n\nexport function combineSelections(selections: Selection[]): CombinedSelection[] {\n return values(\n selections.reduce((output: {[key: string]: any}, [id, fields], index) => {\n const key = sortBy(fields.join(','), identity).join('.')\n if (!output[key]) {\n output[key] = {fields: fields, ids: [], map: []}\n }\n const idx = output[key].ids.length\n output[key].ids[idx] = id\n output[key].map[idx] = index\n return output\n }, {}),\n )\n}\n\nfunction stringifyId(id: string) {\n return JSON.stringify(id)\n}\n\nconst maybeEscape = (fieldName: string) =>\n fieldNeedsEscape(fieldName) ? `\"${fieldName}\": @${escapeField(fieldName)}` : fieldName\n\nfunction toSubQuery({ids, fields}: {ids: string[]; fields: string[]}) {\n const allFields = [...INCLUDE_FIELDS_QUERY, ...fields]\n return `*[_id in [${ids.map(stringifyId).join(',')}]][0...${ids.length}]{${allFields\n .map(maybeEscape)\n .join(',')}}`\n}\n\nexport function toQuery(combinedSelections: CombinedSelection[]): string {\n return `[${combinedSelections.map(toSubQuery).join(',')}][0...${combinedSelections.length}]`\n}\n\nexport function reassemble(\n queryResult: Result[],\n combinedSelections: CombinedSelection[],\n): (Doc | null)[] {\n return queryResult.reduce((reprojected: (Doc | null)[], subResult, index) => {\n const map = combinedSelections[index].map\n map.forEach((resultIdx, i) => {\n const id = combinedSelections[index].ids[i]\n const found = subResult.find((doc) => doc._id === id)\n reprojected[resultIdx] = found || null\n })\n return reprojected\n }, [])\n}\n","import {type SanityClient, type StackablePerspective} from '@sanity/client'\nimport difference from 'lodash-es/difference.js'\nimport flatten from 'lodash-es/flatten.js'\nimport memoize from 'lodash-es/memoize.js'\nimport {\n combineLatest,\n concat,\n defer,\n EMPTY,\n from,\n fromEvent,\n merge,\n type Observable,\n of,\n retry,\n timer,\n} from 'rxjs'\nimport {\n distinctUntilChanged,\n filter,\n map,\n mergeMap,\n reduce,\n share,\n shareReplay,\n startWith,\n switchMap,\n tap,\n} from 'rxjs/operators'\n\nimport {RELEASES_STUDIO_CLIENT_OPTIONS} from '../releases/util/releasesClient'\nimport {versionedClient} from '../studioClient'\nimport {MAX_DOCUMENT_ID_CHUNK_SIZE} from '../util/const'\nimport {getPublishedId, idMatchesPerspective, isVersionId} from '../util/draftUtils'\nimport {variantApiVersion} from '../variants/util/variantApiVersion'\nimport {INCLUDE_FIELDS} from './constants'\nimport {\n type ApiConfig,\n type FieldName,\n type Id,\n type InvalidationChannelEvent,\n type Selection,\n} from './types'\nimport {debounceCollect} from './utils/debounceCollect'\nimport {hasEqualFields} from './utils/hasEqualFields'\nimport {isUniqueBy} from './utils/isUniqueBy'\nimport {type CombinedSelection, combineSelections, reassemble, toQuery} from './utils/optimizeQuery'\n\n/**\n * Chunks combined selections into smaller groups based on the total byte size of document IDs.\n * This prevents queries from becoming too large and timing out.\n *\n * Similar to chunkDocumentIds in availability.ts, but handles CombinedSelection structure.\n *\n * @param combinedSelections - The combined selections to chunk\n * @returns Array of chunked combined selections, each within the size limit\n * @internal\n */\nexport function chunkCombinedSelections(\n combinedSelections: CombinedSelection[],\n): CombinedSelection[][] {\n const chunks: CombinedSelection[][] = []\n\n for (const selection of combinedSelections) {\n let chunk: string[] = []\n let chunkMap: number[] = []\n let chunkSize = 0\n\n for (let i = 0; i < selection.ids.length; i++) {\n const id = selection.ids[i]\n // +3 accounts for quotes and comma in GROQ request structure: [\"id1\",\"id2\"]\n const idSize = id.length + 3\n\n // Reached the max length? Start a new chunk\n if (chunkSize + idSize >= MAX_DOCUMENT_ID_CHUNK_SIZE && chunk.length > 0) {\n chunks.push([{ids: chunk, fields: selection.fields, map: chunkMap}])\n chunk = []\n chunkMap = []\n chunkSize = 0\n }\n\n chunk.push(id)\n chunkMap.push(selection.map[i])\n chunkSize += idSize\n }\n\n // Push overflowing IDs to the last chunk\n // If there are any remaining IDs from the previous check\n if (chunk.length > 0) {\n chunks.push([{ids: chunk, fields: selection.fields, map: chunkMap}])\n }\n }\n\n return chunks\n}\n\n/**\n * Cache key for the combination of perspective stack and variant a fetch is scoped to. Preview\n * values differ per combination, so caches must never be shared across them.\n */\nfunction getPerspectiveCacheKey(\n perspective: StackablePerspective[] | undefined,\n variant: string | undefined,\n): string {\n const perspectiveKey = perspective?.join('-') || 'raw'\n return variant ? `${perspectiveKey}-variant:${variant}` : perspectiveKey\n}\n\ntype CachedFieldObserver = {\n id: Id\n fields: FieldName[]\n changes$: Observable<any>\n}\n\ntype Cache = {\n [id: string]: CachedFieldObserver[]\n}\n\n/**\n * Note: this should be the minimal interface createObserveFields needs to function\n * It should be kept compatible with the Sanity Client\n */\nexport interface ClientLike {\n withConfig(config: ApiConfig): ClientLike\n observable: {\n fetch: (\n query: string,\n params: Record<string, string>,\n options: {tag: string},\n ) => Observable<unknown>\n }\n}\n\n/**\n * Creates a function that allows observing individual fields on a document.\n * It will automatically debounce and batch requests, and maintain an in-memory cache of the latest field values\n * @param options - Options to use when creating the observer\n * @internal\n */\nexport function createObserveFields(options: {\n client: SanityClient\n invalidationChannel: Observable<InvalidationChannelEvent>\n}) {\n const {client: currentDatasetClient, invalidationChannel} = options\n\n function fetchAllDocumentPathsWith(\n client: SanityClient,\n perspective?: StackablePerspective[],\n variant?: string,\n ) {\n return function fetchAllDocumentPath(selections: Selection[]) {\n const combinedSelections = combineSelections(selections)\n // If any document is a version document we need to use the release API version\n const useReleaseVersion =\n (perspective && perspective.length > 0) ||\n combinedSelections.some((selection) => selection.ids.some(isVersionId))\n\n const apiClient = versionedClient(\n client,\n variantApiVersion(\n variant,\n useReleaseVersion ? RELEASES_STUDIO_CLIENT_OPTIONS.apiVersion : undefined,\n ),\n )\n\n // Chunk the selections to avoid massive queries that timeout\n const selectionChunks = chunkCombinedSelections(combinedSelections)\n\n // Helper to fetch a single chunk\n const fetchChunk = (chunk: CombinedSelection[]) =>\n apiClient.observable\n .fetch(toQuery(chunk), {}, {tag: 'preview.document-paths', perspective, variant})\n .pipe(\n retry({\n delay: (_: unknown, attempt) => timer(Math.min(30_000, attempt * 1000)),\n }),\n map((result: any) => reassemble(result, chunk)),\n )\n\n // No chunks - return empty array early\n if (selectionChunks.length === 0) {\n return of([])\n }\n\n // Single chunk - no merging needed (most common case)\n // Kept for performance reasons, as it is the common case (no massive releases) and faster\n if (selectionChunks.length === 1) {\n return fetchChunk(selectionChunks[0])\n }\n\n // Multiple chunks - fetch in parallel and merge results\n // Each chunk's reassemble places results at their original map indices\n // We collect all results and build the final array at the end\n const totalSelections = selections.length\n return from(selectionChunks).pipe(\n mergeMap(fetchChunk, 10),\n reduce((merged: (Record<string, any> | null)[], chunkResults) => {\n chunkResults.forEach((result, idx) => {\n if (result !== null && result !== undefined) merged[idx] = result\n })\n return merged\n }, new Array(totalSelections).fill(null)),\n )\n }\n }\n const batchFetchersCache = new Map()\n function getBatchFetchersForPerspective(perspective?: StackablePerspective[], variant?: string) {\n const key = getPerspectiveCacheKey(perspective, variant)\n if (batchFetchersCache.has(key)) {\n return batchFetchersCache.get(key)\n }\n const batchFetchers = {\n fast: debounceCollect(\n fetchAllDocumentPathsWith(currentDatasetClient, perspective, variant),\n 100,\n ),\n slow: debounceCollect(\n fetchAllDocumentPathsWith(currentDatasetClient, perspective, variant),\n 1000,\n ),\n }\n batchFetchersCache.set(key, batchFetchers)\n return batchFetchers\n }\n\n function currentDatasetListenFields(\n documentId: Id,\n fields: FieldName[],\n perspective?: StackablePerspective[],\n variant?: string,\n ) {\n const {fast: fetchDocumentPathsFast, slow: fetchDocumentPathsSlow} =\n getBatchFetchersForPerspective(perspective, variant)\n\n const hasPerspective = perspective && perspective.length > 0\n /**\n * Q: Why are we using published id if perspective is provided?\n * A: Normally, queries for fetching preview values will be based on the _id of the document,\n * for example `*[_id == \"drafts.foo\"]`. However, if a perspective passed, the query\n * `*[_id == \"drafts.foo\"]` will not match anything since the `_id` will always be the published id\n * Therefore, if perspective is provided, we need to refetch using the published id instead.\n */\n const fetchId = hasPerspective ? getPublishedId(documentId) : documentId\n\n return invalidationChannel.pipe(\n filter((event) => {\n // we always want to fetch when the listener just (re) connected\n if (event.type === 'connected') {\n return true\n }\n if (hasPerspective) {\n // With perspectives, refetch only when the mutated document is a\n // version of the observed document (same base/published id) AND that\n // version is relevant to the current perspective stack (e.g. drafts,\n // a specific release). This avoids refetching for unrelated documents\n // or versions outside the active perspective.\n if (getPublishedId(event.documentId) !== getPublishedId(documentId)) {\n return false\n }\n // Variant documents are `versions.<opaqueScopeId>.<groupId>`, and scope ids never appear\n // in the perspective stack, so the stack check can't recognise them. Under a variant\n // selection, any mutation within the document group is treated as relevant.\n return Boolean(variant) || idMatchesPerspective(perspective, event.documentId)\n }\n // if not using perspective, refetch previews for the document that was actually changed\n return event.documentId === documentId\n }),\n switchMap((event) => {\n if (event.type === 'connected' || event.visibility === 'query') {\n return fetchDocumentPathsFast(fetchId, fields).pipe(\n mergeMap((result) => {\n return concat(\n of(result),\n result === null // hack: if we get undefined as result here it can be because the document has\n ? // just been created and is not yet indexed. We therefore need to wait a bit\n // and then re-fetch.\n fetchDocumentPathsSlow(fetchId, fields)\n : [],\n )\n }),\n )\n }\n return fetchDocumentPathsSlow(fetchId, fields)\n }),\n )\n }\n\n const CACHE: Cache = {} // todo: use a LRU cache instead (e.g. hashlru or quick-lru)\n\n const getBatchFetcherForDataset = memoize(\n function getBatchFetcherForDataset(apiConfig: ApiConfig) {\n const client = currentDatasetClient.withConfig(apiConfig)\n const fetchAll = fetchAllDocumentPathsWith(client, ['drafts'])\n return debounceCollect(fetchAll, 10)\n },\n (apiConfig) => apiConfig.dataset + apiConfig.projectId,\n )\n\n const CROSS_DATASET_PREVIEW_POLL_INTERVAL = 10000\n // We want to poll for changes in the other dataset, but only when window/tab is visible\n // This sets up a shared stream that emits an event every `POLL_INTERVAL` milliseconds as long as the\n // document is visible. It starts emitting immediately (if the page is visible)\n const visiblePoll$ = fromEvent(document, 'visibilitychange').pipe(\n startWith(0),\n map(() => document.visibilityState === 'visible'),\n switchMap((visible) => (visible ? timer(0, CROSS_DATASET_PREVIEW_POLL_INTERVAL) : EMPTY)),\n share(),\n )\n\n function crossDatasetListenFields(id: Id, fields: FieldName[], apiConfig: ApiConfig) {\n return visiblePoll$.pipe(startWith(0)).pipe(\n switchMap(() => {\n const batchFetcher = getBatchFetcherForDataset(apiConfig)\n return batchFetcher(id, fields)\n }),\n )\n }\n\n function createCachedFieldObserver<T>(\n id: string,\n fields: FieldName[],\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ): CachedFieldObserver {\n // Note: `undefined` means the memo has not been set, while `null` means the memo is explicitly set to null (e.g. we did fetch, but got null back)\n let latest: T | undefined | null\n const changes$ = merge(\n defer(() => (latest === undefined ? EMPTY : of(latest))),\n (apiConfig\n ? (crossDatasetListenFields(id, fields, apiConfig) as any)\n : currentDatasetListenFields(id, fields, perspective, variant)) as Observable<T>,\n ).pipe(\n tap((v: T | null) => (latest = v)),\n shareReplay({refCount: true, bufferSize: 1}),\n )\n\n return {id, fields, changes$}\n }\n\n function cachedObserveFields(\n id: Id,\n fields: FieldName[],\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ) {\n const cacheKey = apiConfig\n ? `${apiConfig.projectId}:${apiConfig.dataset}:${id}`\n : `$current$-${id}-${getPerspectiveCacheKey(perspective, variant)}`\n\n if (!(cacheKey in CACHE)) {\n CACHE[cacheKey] = []\n }\n\n const existingObservers = CACHE[cacheKey]\n const missingFields = difference(\n fields,\n flatten(existingObservers.map((cachedFieldObserver) => cachedFieldObserver.fields)),\n )\n\n if (missingFields.length > 0) {\n existingObservers.push(createCachedFieldObserver(id, fields, apiConfig, perspective, variant))\n }\n\n const cachedFieldObservers = existingObservers\n .filter((observer) => observer.fields.some((fieldName) => fields.includes(fieldName)))\n .map((cached) => cached.changes$)\n\n return combineLatest(cachedFieldObservers).pipe(\n // in the event that a document gets deleted, the cached values will be updated to store `undefined`\n // if this happens, we should not pick any fields from it, but rather just return null\n map((snapshots) => snapshots.filter(Boolean)), // make sure all snapshots agree on same revision\n filter((snapshots) => isUniqueBy(snapshots, (snapshot) => snapshot._rev)), // pass on value with the requested fields (or null if value is deleted)\n map((snapshots) => (snapshots.length === 0 ? null : pickFrom(snapshots, fields))), // emit values only if changed\n distinctUntilChanged(hasEqualFields(fields)),\n )\n }\n\n return cachedObserveFields\n\n function pickFrom(objects: Record<string, any>[], fields: string[]) {\n return [...INCLUDE_FIELDS, ...fields].reduce((result, fieldName) => {\n const value = getFirstFieldValue(objects, fieldName)\n if (value !== undefined) {\n ;(result as any)[fieldName] = value\n }\n return result\n }, {})\n }\n\n function getFirstFieldValue(objects: Record<string, any>[], fieldName: string) {\n let value\n objects.some((object) => {\n if (fieldName in object) {\n value = object[fieldName]\n return true\n }\n return false\n })\n return value\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {dequal as isEqual} from 'dequal/lite'\nimport {concat, from, type Observable, of, type OperatorFunction, retry, Subject, timer} from 'rxjs'\nimport {\n bufferWhen,\n distinctUntilChanged,\n filter,\n finalize,\n map,\n mergeMap,\n shareReplay,\n switchMap,\n tap,\n toArray,\n} from 'rxjs/operators'\n\nimport {RELEASES_STUDIO_CLIENT_OPTIONS} from '../releases/util/releasesClient'\nimport {versionedClient} from '../studioClient'\nimport {MAX_DOCUMENT_ID_CHUNK_SIZE} from '../util/const'\nimport {getPublishedId} from '../util/draftUtils'\nimport {type InvalidationChannelEvent} from './types'\nimport {debounceCollect} from './utils/debounceCollect'\n\n/**\n * Approximate per-id overhead of a single document group member subquery.\n */\nconst VERSION_OF_QUERY_OVERHEAD = '*[sanity::versionOf(\"\")]._id,'.length\n\n/**\n * Maximum number of batch queries to keep in flight at once.\n */\nconst MAX_CONCURRENT_BATCH_FETCHES = 10\n\n/**\n * Create a function that observes the set of version and variant document ids\n * that exist for the provided document group id.\n *\n * Unlike `createDocumentIdSetObserver`, which opens a dedicated listener for\n * each document group id, this observer is driven by the shared global\n * `invalidationChannel`. It condenses the queries for all observed document\n * group ids into a single GROQ query (one `sanity::versionOf()` call per id),\n * batching the request if it exceeds `MAX_DOCUMENT_ID_BATCH_SIZE`.\n *\n * @internal\n */\nexport function createObserveVersionDocumentIds(options: {\n client: SanityClient\n invalidationChannel: Observable<InvalidationChannelEvent>\n}): (documentGroupId: string) => Observable<string[]> {\n const {client, invalidationChannel} = options\n const releasesClient = versionedClient(client, RELEASES_STUDIO_CLIENT_OPTIONS.apiVersion)\n\n const fetchFast = debounceCollect(\n (collectedArgs: [documentGroupId: string][]) =>\n fetchVersionIdSets(releasesClient, collectedArgs),\n 100,\n )\n\n const fetchSlow = debounceCollect(\n (collectedArgs: [documentGroupId: string][]) =>\n fetchVersionIdSets(releasesClient, collectedArgs),\n 1000,\n )\n\n const cache = new Map<string, Observable<string[]>>()\n\n return function observeVersionDocumentIds(documentGroupId: string): Observable<string[]> {\n const cachedInstance = cache.get(documentGroupId)\n\n if (cachedInstance) {\n return cachedInstance\n }\n\n const instance = invalidationChannel.pipe(\n filter(\n (event) =>\n event.type === 'connected' || getPublishedId(event.documentId) === documentGroupId,\n ),\n switchMap((event) => {\n if (event.type === 'connected' || event.visibility === 'query') {\n return fetchFast(documentGroupId).pipe(\n mergeMap((ids) => {\n // A newly created version may not be indexed yet when its mutation\n // event arrives. If the mutated document isn't reflected in the\n // fresh result, schedule a slow refetch to catch up (mirroring the\n // fast/slow fallback in `observeFields`).\n const maybeIndexPending =\n event.type === 'mutation' &&\n event.documentId !== documentGroupId &&\n !ids.includes(event.documentId)\n\n if (maybeIndexPending) {\n return concat(of(ids), fetchSlow(documentGroupId))\n }\n\n return of(ids)\n }),\n )\n }\n return fetchSlow(documentGroupId)\n }),\n distinctUntilChanged(isEqual),\n finalize(() => cache.delete(documentGroupId)),\n shareReplay({\n refCount: true,\n bufferSize: 1,\n }),\n )\n\n cache.set(documentGroupId, instance)\n return instance\n }\n}\n\n/**\n * Buffer source values into batches, closing the current batch just before a\n * value would push its cumulative byte size to or beyond `maxBytes`. The\n * overflowing value becomes the first entry of the next batch; a value whose\n * own size already meets the limit is emitted as a single-element batch.\n *\n * @internal\n */\nexport function bufferByByteSize<Type extends string>(\n byteSize: (value: Type) => number,\n maxBytes: number,\n): OperatorFunction<Type, Type[]> {\n return (source) => {\n const closeBuffer = new Subject<void>()\n let bufferedBytes = 0\n\n return source.pipe(\n tap((value) => {\n const size = byteSize(value)\n // Close the current (non-empty) buffer before this value would exceed\n // the limit, so the overflowing value becomes the first entry of the\n // next buffer instead.\n if (bufferedBytes > 0 && bufferedBytes + size >= maxBytes) {\n bufferedBytes = 0\n closeBuffer.next()\n }\n bufferedBytes += size\n }),\n bufferWhen(() => closeBuffer),\n )\n }\n}\n\nfunction buildQuery(documentGroupIds: string[]): string {\n const subQueries = documentGroupIds.map((id) => `*[sanity::versionOf(${JSON.stringify(id)})]._id`)\n return `[${subQueries.join(',')}]`\n}\n\nfunction fetchBatch(client: SanityClient, ids: string[]): Observable<string[][]> {\n return client.observable\n .fetch<string[][]>(buildQuery(ids), {}, {tag: 'preview.observe-version-ids'})\n .pipe(\n retry({delay: (_: unknown, attempt) => timer(Math.min(30_000, attempt * 1000))}),\n // Sort each set ascending so consumers get a stable order.\n map((result) => result.map((versionIds) => [...versionIds].sort())),\n )\n}\n\nfunction fetchVersionIdSets(\n client: SanityClient,\n collectedArgs: [documentGroupIds: string][],\n): Observable<string[][]> {\n const documentGroupIds = collectedArgs.map(([documentGroupId]) => documentGroupId)\n\n if (documentGroupIds.length === 0) {\n return of([])\n }\n\n return from(documentGroupIds).pipe(\n // Split into batches small enough that each combined query stays within the\n // max query size.\n bufferByByteSize((id) => id.length + VERSION_OF_QUERY_OVERHEAD, MAX_DOCUMENT_ID_CHUNK_SIZE),\n // Fetch batches in parallel, tracking each batch's position so results can\n // be reordered.\n mergeMap(\n (batch, index) => fetchBatch(client, batch).pipe(map((result) => ({index, result}))),\n MAX_CONCURRENT_BATCH_FETCHES,\n ),\n toArray(),\n // Restore source order (parallel fetches may settle out of order), and\n // flatten the batch results back into a single array aligned with\n // `documentGroupIds`.\n map((settled) => settled.sort((a, b) => a.index - b.index).flatMap(({result}) => result)),\n )\n}\n","import {\n type MutationEvent,\n type QueryParams,\n type SanityClient,\n type StackablePerspective,\n type WelcomeEvent,\n} from '@sanity/client'\nimport {type DocumentSystem, type PrepareViewOptions, type SanityDocument} from '@sanity/types'\nimport {combineLatest, type Observable} from 'rxjs'\nimport {distinctUntilChanged, filter, map} from 'rxjs/operators'\n\nimport {isRecord} from '../util/isRecord'\nimport {\n createDocumentStackAvailabilityObserver,\n createPreviewAvailabilityObserver,\n} from './availability'\nimport {DOCUMENT_SYSTEM_FIELD} from './constants'\nimport {createGlobalListener} from './createGlobalListener'\nimport {createObserveDocument, type ObserveDocumentAPIConfig} from './createObserveDocument'\nimport {createPathObserver} from './createPathObserver'\nimport {createPreviewObserver} from './createPreviewObserver'\nimport {createObservePathsDocumentPair} from './documentPair'\nimport {createDocumentIdSetObserver, type DocumentIdSetObserverState} from './liveDocumentIdSet'\nimport {createObserveFields} from './observeFields'\nimport {createObserveVersionDocumentIds} from './observeVersionDocumentIds'\nimport {\n type ApiConfig,\n type DocumentStackAvailability,\n type DraftsModelDocument,\n type DraftsModelDocumentAvailability,\n type ObservePathsFn,\n type PreparedSnapshot,\n type Previewable,\n type PreviewableType,\n type PreviewPath,\n} from './types'\n\n/**\n * @hidden\n * @beta */\nexport type ObserveForPreviewFn = (\n value: Previewable,\n type: PreviewableType,\n options?: {\n viewOptions?: PrepareViewOptions\n perspective?: StackablePerspective[]\n /**\n * The selected editing variant as a bare variant id. When set, preview values are resolved as\n * seen through that variant, on top of the given perspective.\n */\n variant?: string\n apiConfig?: ApiConfig\n },\n) => Observable<PreparedSnapshot>\n\n/**\n * The document preview store supports subscribing to content for previewing purposes.\n * Documents observed by this store will be kept in sync and receive real-time updates from all collaborators,\n * but has no support for optimistic updates, so any local edits will require a server round-trip before becoming visible,\n * which means this store is less suitable for real-time editing scenarios.\n *\n * @hidden\n * @beta */\nexport interface DocumentPreviewStore {\n observePaths: ObservePathsFn\n observeForPreview: ObserveForPreviewFn\n observeDocumentTypeFromId: (\n id: string,\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ) => Observable<string | undefined>\n observeDocumentSystemFromId: (\n id: string,\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ) => Observable<DocumentSystem | undefined>\n\n /**\n *\n * @hidden\n * @beta\n */\n unstable_observeDocumentPairAvailability: (\n id: string,\n options?: {version?: string},\n ) => Observable<DraftsModelDocumentAvailability>\n\n /**\n *\n * @hidden\n * @beta\n */\n unstable_observeDocumentStackAvailability: (\n id: string,\n perspectiveStack: StackablePerspective[],\n ) => Observable<DocumentStackAvailability[]>\n\n unstable_observePathsDocumentPair: <T extends SanityDocument = SanityDocument>(\n id: string,\n paths: PreviewPath[],\n options?: {version?: string},\n ) => Observable<DraftsModelDocument<T>>\n\n /**\n * Observes a set of document IDs that matches the given groq-filter. The document ids are returned in ascending order and will update in real-time\n * Whenever a document appears or disappears from the set, a new array with the updated set of IDs will be pushed to subscribers.\n * The query is performed once, initially, and thereafter the set of ids are patched based on the `appear` and `disappear`\n * transitions on the received listener events.\n * This provides a lightweight way of subscribing to a list of ids for simple cases where you just want to subscribe to a set of documents ids\n * that matches a particular filter.\n *\n * @hidden\n * @beta\n * @param filter - A groq filter to use for the document set\n * @param params - Parameters to use with the groq filter\n * @param options - Options for the observer\n * @param apiVersion - Specify the API version to use for the query\n */\n unstable_observeDocumentIdSet: (\n filter: string,\n params?: QueryParams,\n options?: {\n /**\n * Where to insert new items into the set. Defaults to 'sorted' which is based on the lexicographic order of the id\n */\n insert?: 'sorted' | 'prepend' | 'append'\n apiVersion?: string\n },\n ) => Observable<DocumentIdSetObserverState>\n\n /**\n * Observes the set of version and variant document ids that exist for a given\n * document group id.\n *\n * Unlike `unstable_observeDocumentIdSet`, this does not open a dedicated\n * real-time listener for each published id. Instead, it is driven by the\n * shared global listener and batches the discovery queries for all observed\n * document group ids into a single combined query, returning the ids in\n * ascending order.\n *\n * @hidden\n * @beta\n */\n unstable_observeVersionDocumentIds: (publishedId: string) => Observable<string[]>\n\n /**\n * Observe a complete document with the given ID\n *\n * @hidden\n * @beta\n */\n unstable_observeDocument: (\n id: string,\n clientConfig?: ObserveDocumentAPIConfig,\n ) => Observable<SanityDocument | undefined>\n\n /**\n * Observe a list of complete documents with the given IDs\n *\n * @hidden\n * @beta\n */\n unstable_observeDocuments: (\n ids: string[],\n clientConfig?: ObserveDocumentAPIConfig,\n ) => Observable<(SanityDocument | undefined)[]>\n}\n\n/** @internal */\nexport interface DocumentPreviewStoreOptions {\n client: SanityClient\n}\n\n/** @internal */\nexport function createDocumentPreviewStore({\n client,\n}: DocumentPreviewStoreOptions): DocumentPreviewStore {\n const versionedClient = client.withConfig({apiVersion: '2025-02-19'})\n const globalListener = createGlobalListener(versionedClient).pipe(\n filter(\n (event): event is MutationEvent | WelcomeEvent =>\n // ignore reconnect events for now until we've verified that downstream consumers can handle them\n event.type === 'mutation' || event.type === 'welcome',\n ),\n )\n const invalidationChannel = globalListener.pipe(\n map((event) => (event.type === 'welcome' ? {type: 'connected' as const} : event)),\n )\n\n const observeDocument = createObserveDocument({client, mutationChannel: globalListener})\n const observeFields = createObserveFields({client: versionedClient, invalidationChannel})\n const observePaths = createPathObserver({observeFields})\n\n function observeDocumentTypeFromId(\n id: string,\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n ): Observable<string | undefined> {\n return observePaths(\n {_type: 'reference', _ref: id},\n ['_type'],\n apiConfig,\n perspective,\n variant,\n ).pipe(\n map((res) => (isRecord(res) && typeof res._type === 'string' ? res._type : undefined)),\n distinctUntilChanged(),\n )\n }\n function observeDocumentSystemFromId(\n id: string,\n apiConfig?: ApiConfig,\n perspective?: StackablePerspective[],\n variant?: string,\n // TODO: This shouldn't be undefined once the documents are migrated.\n ): Observable<DocumentSystem | undefined> {\n return observePaths(\n {_type: 'reference', _ref: id},\n [DOCUMENT_SYSTEM_FIELD],\n apiConfig,\n perspective,\n variant,\n ).pipe(\n map((res) =>\n isRecord(res) && isRecord(res[DOCUMENT_SYSTEM_FIELD])\n ? (res[DOCUMENT_SYSTEM_FIELD] as unknown as DocumentSystem)\n : undefined,\n ),\n distinctUntilChanged(),\n )\n }\n\n const observeDocumentIdSet = createDocumentIdSetObserver(versionedClient)\n\n const observeVersionDocumentIds = createObserveVersionDocumentIds({\n client: versionedClient,\n invalidationChannel,\n })\n\n const observeForPreview = createPreviewObserver({observeDocumentTypeFromId, observePaths})\n\n const observeDocumentStackAvailability = createDocumentStackAvailabilityObserver(\n versionedClient,\n observePaths,\n )\n const observeDocumentPairAvailability = createPreviewAvailabilityObserver(\n versionedClient,\n observePaths,\n )\n\n const observePathsDocumentPair = createObservePathsDocumentPair({\n observeDocumentPairAvailability,\n observePaths,\n })\n\n // @todo: explain why the API is like this now, and that it should not be like this in the future!\n\n return {\n observePaths,\n observeForPreview,\n observeDocumentTypeFromId,\n observeDocumentSystemFromId,\n unstable_observeDocumentIdSet: observeDocumentIdSet,\n unstable_observeVersionDocumentIds: observeVersionDocumentIds,\n unstable_observeDocument: observeDocument,\n unstable_observeDocuments: (ids: string[]) =>\n combineLatest(ids.map((id) => observeDocument(id))),\n unstable_observeDocumentPairAvailability: observeDocumentPairAvailability,\n unstable_observeDocumentStackAvailability: observeDocumentStackAvailability,\n unstable_observePathsDocumentPair: observePathsDocumentPair,\n }\n}\n","import {createNode} from '@sanity/comlink'\nimport {type FrameMessages, type WindowMessages} from '@sanity/message-protocol'\n\nimport {type CapabilityRecord} from '../renderingContext/types'\nimport {type ComlinkStore} from './types'\n\ninterface Options {\n capabilities: CapabilityRecord\n}\n\n// These values must match the bindings of the same name exported by `@sanity/message-protocol`.\n// We are currently unable to consume this package at runtime because of ESM issues.\n//\n// TODO: Consume `SDK_CHANNEL_NAME` and `SDK_NODE_NAME` from `@sanity/message-protocol`.\nconst SDK_CHANNEL_NAME = 'dashboard/channels/sdk'\nconst SDK_NODE_NAME = 'dashboard/nodes/sdk'\n\nfunction noop() {}\n\n/**\n * Create a Comlink node if Comlink is provided by the Studio rendering context. The node is not\n * started here — the store is created during render — but by the first `start()` call, which\n * `useComlinkStore` makes once the consumer has committed.\n *\n * @internal\n */\nexport function createComlinkStore({capabilities}: Options): ComlinkStore {\n if (!capabilities.comlink) {\n return {start: noop}\n }\n\n const node = createNode<FrameMessages, WindowMessages>({\n name: SDK_NODE_NAME,\n connectTo: SDK_CHANNEL_NAME,\n })\n\n let started = false\n\n return {\n node,\n start: () => {\n if (started) return\n started = true\n node.start()\n },\n }\n}\n","import {type Observable, type OperatorFunction} from 'rxjs'\nimport {catchError, tap} from 'rxjs/operators'\n\ntype Selector<T, K> = (error: unknown, attemptNo: number, caught: Observable<T>) => Observable<K>\n\n/**\n * Like catchError, but passes the number of successive errors as the second argument to the selector function\n * @internal\n * @hidden\n */\nexport function catchWithCount<T, K = T>(selector: Selector<T, K>): OperatorFunction<T, K>\nexport function catchWithCount<T, K = T>(selector: Selector<T, K>) {\n return (input$: Observable<T>) => {\n let successiveErrorsCount = 0\n\n const errorOp: OperatorFunction<any, any> = catchError(\n (err: unknown, caught: Observable<T>) => {\n successiveErrorsCount++\n return selector(err, successiveErrorsCount, caught).pipe(errorOp)\n },\n )\n return input$.pipe(\n tap(() => {\n // Reset when source stream emits a value (i.e. not errors)\n successiveErrorsCount = 0\n }),\n errorOp,\n )\n }\n}\n","import {type BifurClient} from '@sanity/bifur-client'\nimport {observableCallback} from 'observable-callback'\nimport {concat, fromEvent, merge, NEVER, type Observable, of, throwError, timer} from 'rxjs'\nimport {map, mergeMapTo, startWith, take, takeUntil} from 'rxjs/operators'\n\nimport {catchWithCount} from '../../util/catchWithCount'\n\n/** @internal */\nexport interface ConnectionStatusStore {\n connectionStatus$: Observable<ConnectionStatus>\n}\n\nconst onOnline$ = typeof window === 'undefined' ? of({}) : fromEvent(window, 'online')\nconst onOffline$ = typeof window === 'undefined' ? of({}) : fromEvent(window, 'offline')\n\nconst expBackoff = (retryCount: number) => Math.pow(2, retryCount) * 100\n\n/** @internal */\nexport type ConnectingStatus = {\n type: 'connecting'\n}\n\n/** @internal */\nexport type ErrorStatus = {\n type: 'error'\n error: Error\n attemptNo: number\n isOffline: boolean\n retryAt: Date\n}\n\n/** @internal */\nexport type RetryingStatus = {\n type: 'retrying'\n}\n\n/** @internal */\nexport type ConnectedStatus = {type: 'connected'; lastHeartbeat: Date}\n\n/** @internal */\nexport const CONNECTING: ConnectingStatus = {type: 'connecting'}\n\n/** @internal */\nexport type ConnectionStatus = ConnectingStatus | ErrorStatus | ConnectedStatus | RetryingStatus\n\nconst _callback = observableCallback()\n\nconst onRetry$ = _callback[0]\n\n/** @internal */\nexport const onRetry = _callback[1]\n\nconst createErrorStatus = ({\n error,\n isOffline,\n attemptNo,\n retryAt,\n}: {\n error: Error\n isOffline: boolean\n attemptNo: number\n retryAt: Date\n}): ErrorStatus => ({\n type: 'error',\n error,\n attemptNo,\n isOffline,\n retryAt,\n})\n\n/** @internal */\nexport interface ConnectionStatusStoreOptions {\n bifur: BifurClient\n}\n\n/**\n * This is the beginning of what should be the data store tracking connection status in the Sanity studio.\n *\n * @internal\n */\nexport function createConnectionStatusStore({\n bifur,\n}: ConnectionStatusStoreOptions): ConnectionStatusStore {\n const connectionStatus$: Observable<ConnectionStatus> = merge(\n bifur.heartbeats,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n onOffline$.pipe(mergeMapTo(throwError(new Error('The browser went offline')))),\n ).pipe(\n map((ts): ConnectionStatus => ({type: 'connected', lastHeartbeat: ts})),\n catchWithCount((error, successiveErrorsCount, caught) => {\n const timeUntilRetry = Math.min(1000 * 240, expBackoff(successiveErrorsCount))\n const retryAt = new Date(new Date().getTime() + timeUntilRetry)\n const expiry$ = timer(retryAt)\n const isOffline = !navigator.onLine\n const initialErrorStatus = createErrorStatus({\n error: error as Error,\n retryAt,\n isOffline,\n attemptNo: successiveErrorsCount,\n })\n\n const triggerRetry$ = NEVER.pipe(\n takeUntil(isOffline ? onOnline$ : merge(expiry$, onOnline$, onRetry$)),\n )\n\n return concat(of(initialErrorStatus), triggerRetry$.pipe(take(1)), caught)\n }),\n startWith(CONNECTING),\n )\n\n return {connectionStatus$}\n}\n","import {defineEvent} from '@sanity/telemetry'\n\nexport const DocumentDesynced = defineEvent<{errorName: string}>({\n name: 'Document Desynced',\n version: 1,\n description:\n 'Occurs when a \"hole\" in events from the document pair listener is detected and recovered from.',\n})\n","import {defineEvent} from '@sanity/telemetry'\n\ninterface DocumentPairLoadingMeasuredData {\n /**\n * How long it took to load the document pair\n */\n durationMs: number\n\n /**\n * Whether the document pair was loaded from an in-memory cache\n */\n fromCache: boolean\n\n /**\n * Did we load the published document?\n */\n hasPublished: boolean\n\n /**\n * Did we load the draft document?\n */\n hasDraft: boolean\n\n /**\n * Did we load a version document?\n */\n hasVersion: boolean\n}\n\nexport const DocumentPairLoadingMeasured = defineEvent<DocumentPairLoadingMeasuredData>({\n name: 'Document Pair Load Time Measured',\n version: 1,\n description: 'Time from document pair subscription to first ready snapshot',\n maxSampleRate: 30_000,\n})\n","import {defineEvent} from '@sanity/telemetry'\n\nexport const DocumentRebaseOccurred = defineEvent<{\n remoteMutationCount: number\n localMutationCount: number\n}>({\n name: 'Document Rebase Occurred',\n version: 1,\n description:\n 'A remote mutation arrived while local mutations were pending, requiring a rebase of the optimistic state',\n})\n","import {defineEvent} from '@sanity/telemetry'\n\ntype Samples = {\n latency: number\n transactionId: string\n shard?: string\n}\nexport const HighListenerLatencyOccurred = defineEvent<Samples>({\n name: 'High Listener Latency Detected',\n version: 1,\n description: 'Emits when a high listener latency is detected',\n})\n","import {defineEvent} from '@sanity/telemetry'\n\nexport const MutationPerformanceMeasured = defineEvent<{\n transactionId: string\n debounceMs: number\n apiMs: number\n callbackMs: number\n shard?: string\n}>({\n name: 'Mutation Performance Measured',\n version: 1,\n description:\n 'Timing breakdown for mutation round-trip: debounce, API, and listener callback phases',\n})\n","import {isDraftId, isVersionId} from './draftUtils'\n\n/**\n * Indicates the type of document variant, either `draft`, `version` or `published`.\n * Draft documents are prefixed with `drafts.`.\n * Version documents are prefixed with `versions.<versionName>`\n * The rest are considered published documents.\n * @public\n */\nexport type DocumentVariantType = 'draft' | 'version' | 'published'\n\n/**\n * Takes a document id and returns the variant type for that document\n * If it's a document that starts with `version.` it's a `version` document.\n * If it's a document that starts with `drafts.` it's a `draft` document.\n * Otherwise, it's a `published` document.\n * @public\n * */\nexport function getDocumentVariantType(documentId: string): DocumentVariantType {\n if (isDraftId(documentId)) return 'draft'\n if (isVersionId(documentId)) return 'version'\n return 'published'\n}\n","import {isPortableTextBlock, toPlainText} from '@portabletext/toolkit'\nimport {type DocumentSystem} from '@sanity/types'\n\nimport {type PerspectiveBundle} from '../../perspective/types'\nimport {DOCUMENT_SYSTEM_FIELD} from '../../preview/constants'\nimport {VARIANT_DOCUMENTS_PATH} from '../store/constants'\nimport {type SystemVariant} from '../types'\n\nconst VARIANT_ID_PREFIX = `${VARIANT_DOCUMENTS_PATH}.`\n\n/**\n * Published documents omit `bundleId` on `_system`, but `PerspectiveBundle` also includes the\n * `'published'` literal. Call sites should treat both as published without rewriting the value.\n *\n * @internal\n */\nexport function isPublishedBundleId(bundleId: PerspectiveBundle | undefined): boolean {\n return bundleId === undefined || bundleId === 'published'\n}\n\n/**\n * @internal\n */\nexport function isReleaseBundle(bundleId: PerspectiveBundle | undefined): boolean {\n return !isPublishedBundleId(bundleId) && bundleId !== 'drafts'\n}\n\n/**\n * @internal\n */\nexport function getVariantId(variantDocumentId: string): string {\n return variantDocumentId.startsWith(VARIANT_ID_PREFIX)\n ? variantDocumentId.slice(VARIANT_ID_PREFIX.length)\n : variantDocumentId\n}\n\n/**\n * Returns the short variant id for sticky params from a document's `_system.variant._ref`.\n *\n * @internal\n */\nexport function getVariantIdFromDocument(document: Record<string, unknown>): string | undefined {\n const system = document[DOCUMENT_SYSTEM_FIELD] as DocumentSystem | undefined\n const variantRef = system?.variant?._ref\n\n return variantRef ? getVariantId(variantRef) : undefined\n}\n\n/**\n * @internal\n */\nexport function getVariantTitle(variant: SystemVariant): string {\n const title = variant.metadata?.title\n\n if (typeof title === 'string' && title.trim()) {\n return title\n }\n\n return getVariantId(variant._id)\n}\n\n/**\n * @internal\n */\nexport function getVariantConditionsText(conditions: SystemVariant['conditions']): string {\n return Object.entries(conditions)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join(', ')\n}\n\n/**\n * Decodes router state / URL path segments back to a variant document id.\n *\n * @internal\n */\nexport function decodeVariantIdFromRoute(variantIdRaw: string | undefined): string | undefined {\n if (!variantIdRaw) {\n return undefined\n }\n\n let decoded: string\n\n try {\n decoded = decodeURIComponent(variantIdRaw)\n } catch {\n decoded = variantIdRaw\n }\n\n if (decoded.startsWith(`${VARIANT_ID_PREFIX}`)) {\n return decoded\n }\n\n return `${VARIANT_ID_PREFIX}${decoded}`\n}\n\n/**\n * @internal\n */\nexport function getVariantDescription(variant: SystemVariant): string {\n const description = variant.metadata?.description\n\n if (!Array.isArray(description) || !description.every(isPortableTextBlock)) {\n return ''\n }\n\n return toPlainText(description).trim()\n}\n\n/**\n * @internal\n */\nexport function filterVariantsForSearch(\n variants: SystemVariant[],\n searchTerm: string,\n): SystemVariant[] {\n const normalizedSearchTerm = searchTerm.trim().toLowerCase()\n\n if (!normalizedSearchTerm) {\n return variants\n }\n\n return variants.filter((variant) => {\n const searchableValues = [\n getVariantTitle(variant),\n getVariantId(variant._id),\n ...Object.entries(variant.conditions).flat(),\n ]\n\n return searchableValues.some((value) => value.toLowerCase().includes(normalizedSearchTerm))\n })\n}\n\n/** A filterable condition dimension and the distinct values seen for it across all variants. */\nexport interface ConditionFacet {\n key: string\n values: string[]\n}\n\n/**\n * Derive the filterable facets from every variant's `conditions` key-value pairs: one facet per\n * condition key, with its distinct values. Keys and values are sorted for a stable UI. Because the\n * facets come from the full variant list (not the filtered view), the available options never shrink\n * as filters are applied.\n */\nexport function buildConditionFacets(variants: SystemVariant[]): ConditionFacet[] {\n const valuesByKey = new Map<string, Set<string>>()\n\n for (const variant of variants) {\n for (const [key, value] of Object.entries(variant.conditions)) {\n if (typeof value !== 'string' || value.length === 0) continue\n const values = valuesByKey.get(key) ?? new Set<string>()\n values.add(value)\n valuesByKey.set(key, values)\n }\n }\n\n return Array.from(valuesByKey.entries())\n .map(([key, values]) => ({key, values: Array.from(values).sort((a, b) => a.localeCompare(b))}))\n .sort((a, b) => a.key.localeCompare(b.key))\n}\n\n/**\n * A variant matches when, for every active facet, its value for that condition key is one of the\n * selected values. Selecting several values within one facet is an OR; different facets AND together.\n * An empty selection for a facet imposes no constraint.\n */\nexport function variantMatchesConditionFilters(\n variant: SystemVariant,\n filters: Record<string, string[]>,\n): boolean {\n return Object.entries(filters).every(([key, selectedValues]) => {\n if (selectedValues.length === 0) return true\n const value = variant.conditions[key]\n return typeof value === 'string' && selectedValues.includes(value)\n })\n}\n","import {BufferedDocument, Mutation} from '@sanity/mutator'\nimport {type SanityDocument} from '@sanity/types'\nimport {BehaviorSubject, EMPTY, merge, type Observable, Subject} from 'rxjs'\nimport {\n distinctUntilChanged,\n filter,\n map,\n mergeMapTo,\n publishReplay,\n refCount,\n scan,\n share,\n take,\n tap,\n withLatestFrom,\n} from 'rxjs/operators'\n\nimport {type ListenerEvent} from '../getPairListener'\nimport {type MutationEvent} from '../types'\nimport {\n type DocumentMutationEvent,\n type DocumentRebaseEvent,\n type DocumentRemoteMutationEvent,\n type MutationPayload,\n type RemoteSnapshotEvent,\n type SnapshotEvent,\n} from './types'\n\ninterface MutationAction {\n type: 'mutation'\n mutations: MutationPayload[]\n}\n\ninterface CommitAction {\n type: 'commit'\n}\n\ntype Action = MutationAction | CommitAction\n\n/**\n * Represents \"commit requests\" from the mutator.\n * These are emitted from the BufferedDocument instance's `requestHandler` callback\n *\n * @internal\n */\nexport interface CommitRequest {\n mutation: Mutation\n success: () => void\n failure: (error: Error) => void\n cancel: (error: Error) => void\n /** Timestamp (Date.now()) when the first local mutation in this commit batch was received */\n firstMutationReceivedAt?: number\n}\n\n// BufferedDocument.LOCAL never updates its revision due to its internal consistency checks\n// but we sometimes we need the most current _rev on the document in UI land, e.g.\n// in order to do optimistic locking on the edited document to make sure we publish the document the user\n// actually are looking at, and not the one currently at the server\n// Also - the mutator is not setting _updatedAt on patches applied optimistically or\n// when they are received from server\nconst getUpdatedSnapshot = (bufferedDocument: BufferedDocument) => {\n const LOCAL = bufferedDocument.LOCAL\n const HEAD = bufferedDocument.document.HEAD\n if (!LOCAL) {\n return LOCAL\n }\n\n return {\n ...LOCAL,\n _type: (HEAD || LOCAL)._type,\n _rev: (HEAD || LOCAL)._rev,\n _updatedAt: new Date().toISOString(),\n }\n}\n\nconst toSnapshotEvent = (document: any): SnapshotEvent => ({type: 'snapshot', document})\nconst getDocument = <T extends {document: any}>(event: T): T['document'] => event.document\n\n/** @internal */\n// This is an observable interface for BufferedDocument in an attempt\n// to make it easier to work with the api provided by it\nexport const createObservableBufferedDocument = (listenerEvent$: Observable<ListenerEvent>) => {\n // Incoming local actions (e.g. a request to mutate, a request to commit pending changes, etc.)\n const actions$ = new Subject<Action>()\n\n // Track when the first mutation in a batch arrives (for performance telemetry)\n let firstMutationReceivedAt: number | undefined\n\n // Stream of commit requests. Must be handled by a commit handler\n const consistency$ = new BehaviorSubject<boolean>(true)\n\n // Stream of mutations for this document\n // NOTE: this will *not* include remote mutations received over the listener\n // that has *already* applied locally/optimistically\n const mutations$ = new Subject<DocumentMutationEvent>()\n\n // a stream of rebase events emitted from the mutator\n const rebase$ = new Subject<DocumentRebaseEvent>()\n\n // a stream of remote mutations with effetcs\n const remoteMutations = new Subject<DocumentRemoteMutationEvent>()\n\n const commitRequests = new Subject<CommitRequest>()\n\n const createInitialBufferedDocument = (initialSnapshot: SanityDocument | null) => {\n const bufferedDocument = new BufferedDocument(initialSnapshot)\n bufferedDocument.onMutation = ({mutation, remote}: any) => {\n // this is called after either when:\n // 1) local mutations has been added, optimistically applied and queued for sending\n // 2) remote mutations originating from another client has arrived and been applied\n mutations$.next({\n type: 'mutation',\n document: getUpdatedSnapshot(bufferedDocument) as any,\n mutations: mutation.mutations,\n origin: remote ? 'remote' : 'local',\n })\n }\n bufferedDocument.onRemoteMutation = (mutation: any) => {\n remoteMutations.next({\n type: 'remoteMutation',\n head: bufferedDocument.document.HEAD as any,\n transactionId: mutation.transactionId,\n timestamp: mutation.timestamp,\n author: mutation.identity,\n effects: mutation.effects,\n })\n }\n\n bufferedDocument.onRebase = (edge: any, nextRemoteMutations: any, localMutations: any) => {\n rebase$.next({\n type: 'rebase',\n document: edge,\n remoteMutations: nextRemoteMutations,\n localMutations,\n })\n }\n\n bufferedDocument.onConsistencyChanged = (isConsistent) => {\n if (!isConsistent && firstMutationReceivedAt === undefined) {\n firstMutationReceivedAt = Date.now()\n }\n if (isConsistent) {\n firstMutationReceivedAt = undefined\n }\n consistency$.next(isConsistent)\n }\n\n bufferedDocument.commitHandler = (commitArg: CommitRequest) => {\n const captured = firstMutationReceivedAt\n // Reset so the next commit batch doesn't reuse a stale timestamp\n // from a previous batch when the document stays inconsistent\n firstMutationReceivedAt = undefined\n commitRequests.next({...commitArg, firstMutationReceivedAt: captured})\n }\n\n return bufferedDocument\n }\n\n const currentBufferedDocument$ = listenerEvent$.pipe(\n scan((bufferedDocument: BufferedDocument | null, listenerEvent) => {\n // consider renaming 'snapshot' to initial/welcome\n if (listenerEvent.type === 'snapshot') {\n if (bufferedDocument) {\n // we received a new snapshot and already got an old one. When we receive a snapshot again\n // it is usually because the connection has been down. Attempt to save pending changes (if any)\n void bufferedDocument.commit()\n }\n // mark as consistent when a new snapshot is received\n firstMutationReceivedAt = undefined\n consistency$.next(true)\n return createInitialBufferedDocument(listenerEvent.document || null)\n }\n if (bufferedDocument === null) {\n console.warn(\n 'Ignoring event of type \"%s\" since buffered document has not yet been set up with snapshot',\n listenerEvent.type,\n )\n return null\n }\n return bufferedDocument\n }, null),\n filter(\n <T>(bufferedDocument: T): bufferedDocument is NonNullable<T> => bufferedDocument !== null,\n ),\n distinctUntilChanged(),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n refCount(),\n )\n\n // this is a stream of document snapshots where each new snapshot are emitted after listener mutations\n // has been applied. Since the optimistic patches is not emitted on the mutation$ stream, we need this\n // in order to update the document with a new _rev (and _updatedAt)\n const snapshotAfterSync$ = listenerEvent$.pipe(\n filter((ev): ev is MutationEvent => ev.type === 'mutation'),\n withLatestFrom(currentBufferedDocument$),\n map(([mutationEvent, bufferedDocument]) => {\n bufferedDocument.arrive(new Mutation(mutationEvent))\n return getUpdatedSnapshot(bufferedDocument)\n }),\n )\n\n // this is where the side effects mandated by local actions actually happens\n const actionHandler$ = actions$.pipe(\n withLatestFrom(currentBufferedDocument$),\n tap(([action, bufferedDocument]: [Action, BufferedDocument]) => {\n if (action.type === 'mutation') {\n bufferedDocument.add(new Mutation({mutations: action.mutations}))\n }\n if (action.type === 'commit') {\n void bufferedDocument.commit()\n }\n }),\n // We subscribe to this only for the side effects\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n mergeMapTo(EMPTY),\n share(),\n )\n\n const emitAction = (action: any) => actions$.next(action)\n\n const addMutations = (mutations: MutationPayload[]) => emitAction({type: 'mutation', mutations})\n const addMutation = (mutation: MutationPayload) => addMutations([mutation])\n\n const commit = () => {\n currentBufferedDocument$\n .pipe(\n take(1),\n tap((bufferedDocument) => bufferedDocument.commit()),\n )\n .subscribe()\n }\n\n // A stream of this document's snapshot\n const snapshot$ = merge(\n currentBufferedDocument$.pipe(map((bufferedDocument) => bufferedDocument.LOCAL)),\n mutations$.pipe(map(getDocument)),\n rebase$.pipe(map(getDocument)),\n snapshotAfterSync$,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n ).pipe(map(toSnapshotEvent), publishReplay(1), refCount())\n\n const remoteSnapshot$: Observable<RemoteSnapshotEvent> = merge(\n currentBufferedDocument$.pipe(\n map((bufferedDocument) => bufferedDocument.document.HEAD as any),\n map(toSnapshotEvent),\n ),\n remoteMutations,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n ).pipe(publishReplay(1), refCount())\n\n return {\n updates$: merge(snapshot$, actionHandler$, mutations$, rebase$),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n consistency$: consistency$.pipe(distinctUntilChanged(), publishReplay(1), refCount()),\n remoteSnapshot$,\n commitRequest$: commitRequests,\n addMutation,\n addMutations,\n commit,\n }\n}\n","import {type SanityDocument} from '@sanity/types'\nimport {type Observable} from 'rxjs'\n\nimport {type ListenerEvent} from '../getPairListener'\nimport {\n type CommitRequest,\n createObservableBufferedDocument,\n} from './createObservableBufferedDocument'\nimport {\n type CommittedEvent,\n type DocumentMutationEvent,\n type DocumentRebaseEvent,\n type MutationPayload,\n type RemoteSnapshotEvent,\n type SnapshotEvent,\n} from './types'\n\n/**\n * @hidden\n * @beta */\nexport type BufferedDocumentEvent =\n | SnapshotEvent\n | DocumentRebaseEvent\n | DocumentMutationEvent\n | CommittedEvent\n\nconst prepare = (id: string) => (document: Partial<SanityDocument>) => {\n const {_id, _rev, _updatedAt, ...rest} = document\n return {_id: id, ...rest}\n}\n\n/** @internal */\nexport interface BufferedDocumentWrapper {\n consistency$: Observable<boolean>\n remoteSnapshot$: Observable<RemoteSnapshotEvent>\n events: Observable<BufferedDocumentEvent>\n commitRequest$: Observable<CommitRequest>\n // helper functions\n patch: (patches: any[]) => MutationPayload[]\n create: (document: Partial<SanityDocument>) => MutationPayload\n createIfNotExists: (document: SanityDocument) => MutationPayload\n createOrReplace: (document: SanityDocument) => MutationPayload\n delete: () => MutationPayload\n\n mutate: (mutations: MutationPayload[]) => void\n commit: () => void\n}\n\n/** @internal */\nexport const createBufferedDocument = (\n documentId: string,\n // consider naming it remoteEvent$\n listenerEvent$: Observable<ListenerEvent>,\n): BufferedDocumentWrapper => {\n const bufferedDocument = createObservableBufferedDocument(listenerEvent$)\n\n const prepareDoc = prepare(documentId)\n\n const DELETE = {delete: {id: documentId}}\n\n return {\n events: bufferedDocument.updates$,\n consistency$: bufferedDocument.consistency$,\n remoteSnapshot$: bufferedDocument.remoteSnapshot$,\n commitRequest$: bufferedDocument.commitRequest$,\n\n patch: (patches) => patches.map((patch) => ({patch: {...patch, id: documentId}})),\n create: (document) => ({create: prepareDoc(document)}),\n createIfNotExists: (document) => ({createIfNotExists: prepareDoc(document)}),\n createOrReplace: (document) => ({createOrReplace: prepareDoc(document)}),\n delete: () => DELETE,\n\n mutate: (mutations: MutationPayload[]) => bufferedDocument.addMutations(mutations),\n commit: () => bufferedDocument.commit(),\n }\n}\n","import {createDebug} from 'obug'\n\nexport const debug = createDebug('sanity:document-store')\n","import {TTLCache} from '@isaacs/ttlcache'\nimport {type MonoTypeOperatorFunction, type Observable} from 'rxjs'\nimport {mergeMap, scan} from 'rxjs/operators'\n\nimport {debug} from '../debug'\nimport {type ListenerEvent} from '../getPairListener'\n\nconst DEFAULT_TTL = 120_000\nconst DEFAULT_MAX_ENTRIES = 1000\n\nexport function dedupeListenerEvents<T extends ListenerEvent>({\n ttl = DEFAULT_TTL,\n max = DEFAULT_MAX_ENTRIES,\n}: {\n ttl?: number\n max?: number\n} = {}): MonoTypeOperatorFunction<T> {\n return (input$: Observable<T>) =>\n input$.pipe(\n scan(\n ({seen}: {emit: T[]; seen: TTLCache<string, null>}, event: T) => {\n if (event.type !== 'mutation') {\n return {emit: [event], seen}\n }\n const key = `${event.transactionId}#${event.documentId}`\n if (seen.has(key)) {\n debug('Ignoring duplicate listener event: ', key)\n return {seen, emit: []}\n }\n seen.set(key, null)\n return {seen, emit: [event]}\n },\n {emit: [], seen: new TTLCache<string, null>({ttl, max})},\n ),\n mergeMap(\n (state) =>\n // note: if state.emit is an empty array, nothing will be emitted\n state.emit,\n ),\n )\n}\n","import {type MutationEvent} from '../types'\n\nexport function discardChainTo(chain: MutationEvent[], revision: string | undefined) {\n const revisionIndex = chain.findIndex((event) => event.resultRev === revision)\n\n return split(chain, revisionIndex + 1)\n}\n\nfunction split<T>(array: T[], index: number) {\n if (index < 0) {\n return [[], array]\n }\n return [array.slice(0, index), array.slice(index)]\n}\n\nexport function toOrderedChains<T extends {previousRev: string; resultRev: string}>(events: T[]) {\n const parents: Record<string, T | undefined> = {}\n\n events.forEach((event) => {\n parents[event.resultRev] = events.find((other) => other.resultRev === event.previousRev)\n })\n\n // get entries without a parent (if there's more than one, we have a problem)\n const orphans = Object.entries(parents).filter(([, parent]) => {\n return !parent\n })\n\n return orphans.map((orphan) => {\n const [headRev] = orphan\n\n let current = events.find((event) => event.resultRev === headRev)\n\n const sortedList: T[] = []\n while (current) {\n sortedList.push(current)\n current = events.find((event) => event.previousRev === current?.resultRev)\n }\n return sortedList\n })\n}\n","import partition from 'lodash-es/partition.js'\nimport {concat, type Observable, of, switchMap, throwError, timer} from 'rxjs'\nimport {mergeMap, scan} from 'rxjs/operators'\n\nimport {debug} from '../debug'\nimport {type ListenerEvent} from '../getPairListener'\nimport {type MutationEvent} from '../types'\nimport {discardChainTo, toOrderedChains} from './eventChainUtils'\n\ninterface ListenerSequenceState {\n /**\n * Tracks the latest revision from the server that can be applied locally\n * Once we receive a mutation event that has a `previousRev` that equals `base.revision`\n * we will move `base.revision` to the event's `resultRev`\n * `base.revision` will be undefined if document doesn't exist.\n * `base` is `undefined` until the snapshot event is received\n */\n base: {revision: string | undefined} | undefined\n /**\n * Array of events to pass on to the stream, e.g. when mutation applies to current head revision, or a chain is complete\n */\n emitEvents: ListenerEvent[]\n /**\n * Buffer to keep track of events that doesn't line up in a [previousRev, resultRev] -- [previousRev, resultRev] sequence\n * This can happen if events arrive out of order, or if an event in the middle for some reason gets lost\n */\n buffer: MutationEvent[]\n}\n\nconst DEFAULT_MAX_BUFFER_SIZE = 20\nconst DEFAULT_DEADLINE_MS = 30000\n\nconst EMPTY_ARRAY: never[] = []\n\n/**\n * Takes an input observable of listener events that might arrive out of order, and emits them in sequence\n * If we receive mutation events that doesn't line up in [previousRev, resultRev] pairs we'll put them in a buffer and\n * check if we have an unbroken chain every time we receive a new event\n *\n * If the buffer grows beyond `maxBufferSize`, or if `resolveChainDeadline` milliseconds passes before the chain resolves\n * an OutOfSyncError will be thrown on the stream\n *\n * @internal\n */\nexport function sequentializeListenerEvents(options?: {\n maxBufferSize?: number\n resolveChainDeadline?: number\n}) {\n const {resolveChainDeadline = DEFAULT_DEADLINE_MS, maxBufferSize = DEFAULT_MAX_BUFFER_SIZE} =\n options || {}\n\n return (input$: Observable<ListenerEvent>): Observable<ListenerEvent> => {\n return input$.pipe(\n scan(\n (state: ListenerSequenceState, event: ListenerEvent): ListenerSequenceState => {\n if (event.type === 'mutation' && !state.base) {\n throw new Error('Invalid state. Cannot create a sequence without a base')\n }\n if (event.type === 'snapshot') {\n // When receiving a new snapshot, we can safely discard the current orphaned and chainable buffers\n return {\n base: {revision: event.document?._rev},\n buffer: EMPTY_ARRAY,\n emitEvents: [event],\n }\n }\n\n if (event.type === 'mutation') {\n // Note: the buffer may have multiple holes in it (this is a worst case scenario, and probably not likely, but still),\n // so we need to consider all possible chains\n // `toOrderedChains` will return all detected chains and each of the returned chains will be orderered\n // Once we have a list of chains, we can then discard any chain that leads up to the current revision\n // since they are already applied on the document\n const orderedChains = toOrderedChains(state.buffer.concat(event)).map((chain) => {\n // in case the chain leads up to the current revision\n const [discarded, rest] = discardChainTo(chain, state.base!.revision)\n if (discarded.length > 0) {\n debug('Discarded %d mutations already applied to document', discarded.length)\n }\n return rest\n })\n\n const [resolvedChains, _nextBuffer] = partition(orderedChains, (chain) => {\n // note: there can be at most one applicable chain\n return state.base!.revision === chain[0]?.previousRev\n })\n\n const nextBuffer = _nextBuffer\n .flat()\n .toSorted((a, b) => a.messageReceivedAt.localeCompare(b.messageReceivedAt))\n\n if (resolvedChains.length > 1) {\n throw new Error('Expected at most one resolved chain')\n }\n if (resolvedChains.length > 0 && resolvedChains[0].length > 0) {\n // we now have a continuous chain that can apply on the base revision\n // Move current base revision to the last mutation event in the applicable chain\n const lastMutation = resolvedChains[0].at(-1)!\n const nextBaseRevision =\n // special case: if the mutation deletes the document it technically has no revision, despite\n // resultRev pointing at a transaction id.\n lastMutation.transition === 'disappear' ? undefined : lastMutation?.resultRev\n\n if (state.buffer.length > 0) {\n // we went from having unresolved chains to resolved\n debug(\n `Resolved chain: %s => %s`,\n resolvedChains[0][0].previousRev,\n resolvedChains[0].at(-1)?.resultRev,\n )\n if (nextBuffer.length > 0) {\n debug(`There are still %d unchainable mutations`, nextBuffer.length)\n } else {\n debug(`All chains were resolved`)\n }\n }\n return {\n base: {revision: nextBaseRevision},\n emitEvents: resolvedChains[0],\n buffer: nextBuffer,\n }\n }\n\n if (nextBuffer.length >= maxBufferSize) {\n throw new MaxBufferExceededError(\n `Too many unchainable mutation events: ${state.buffer.length}`,\n state,\n )\n }\n return {\n ...state,\n buffer: nextBuffer,\n emitEvents: EMPTY_ARRAY,\n }\n }\n // Any other event (e.g. 'reconnect' is passed on verbatim)\n return {...state, emitEvents: [event]}\n },\n {\n emitEvents: EMPTY_ARRAY,\n base: undefined,\n buffer: EMPTY_ARRAY,\n },\n ),\n switchMap((state) => {\n if (state.buffer.length > 0) {\n // note: buffer is sorted by messageReceivedAt – oldest first\n const brokenChainStartsAt = new Date(state.buffer[0].messageReceivedAt)\n const nextDeadline = resolveChainDeadline - (Date.now() - brokenChainStartsAt.getTime())\n debug(\n \"There are %d listener event(s) that can't be applied in sequence. This could be due to events arriving out of order. Will throw an error if chain can't be resolved within %dms\",\n state.buffer.length,\n nextDeadline,\n )\n debug('Buffered events: %O', state.buffer)\n return concat(\n of(state),\n timer(nextDeadline).pipe(\n mergeMap(() =>\n throwError(() => {\n return new DeadlineExceededError(\n `Did not resolve chain within a deadline of ${resolveChainDeadline}ms`,\n state,\n )\n }),\n ),\n ),\n )\n }\n return of(state)\n }),\n mergeMap((state) => {\n // this will simply flatten the list of events into individual emissions\n // if the flushEvents array is empty, nothing will be emitted\n return state.emitEvents\n }),\n )\n }\n}\n\nexport class OutOfSyncError extends Error {\n /**\n * Attach state to the error for debugging/reporting\n */\n state: ListenerSequenceState\n constructor(message: string, state: ListenerSequenceState) {\n super(message)\n this.name = 'OutOfSyncError'\n this.state = state\n }\n}\n\nexport class DeadlineExceededError extends OutOfSyncError {\n constructor(message: string, state: ListenerSequenceState) {\n super(message, state)\n this.name = 'DeadlineExceededError'\n }\n}\nexport class MaxBufferExceededError extends OutOfSyncError {\n constructor(message: string, state: ListenerSequenceState) {\n super(message, state)\n this.name = 'MaxBufferExceededError'\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type SanityDocument} from '@sanity/types'\nimport groupBy from 'lodash-es/groupBy.js'\nimport {defer, EMPTY, merge, type Observable, of, throwError} from 'rxjs'\nimport {catchError, concatMap, filter, map, mergeMap, scan, share} from 'rxjs/operators'\n\nimport {shareReplayLatest} from '../../preview/utils/shareReplayLatest'\nimport {RELEASES_STUDIO_CLIENT_OPTIONS} from '../../releases/util/releasesClient'\nimport {isConnectionSessionError} from '../../util/apiErrors'\nimport {getVersionFromId} from '../../util/draftUtils'\nimport {type StoreRequestErrorHandler} from '../requestErrorHandler'\nimport {debug} from './debug'\nimport {\n type IdPair,\n type MutationEvent,\n type PendingMutationsEvent,\n type ReconnectEvent,\n type ResetEvent,\n type WelcomeBackEvent,\n type WelcomeEvent,\n} from './types'\nimport {dedupeListenerEvents} from './utils/dedupeListenerEvents'\nimport {OutOfSyncError, sequentializeListenerEvents} from './utils/sequentializeListenerEvents'\n\ninterface Snapshots {\n draft: SanityDocument | null\n published: SanityDocument | null\n version: SanityDocument | null\n}\n\n/** @internal */\nexport interface InitialSnapshotEvent {\n type: 'snapshot'\n documentId: string\n document: SanityDocument | null\n}\n\n/**\n * @internal\n */\nexport interface LatencyReportEvent {\n shard?: string\n latencyMs: number\n transactionId: string\n}\n\n/** @internal */\nexport interface DocumentPairLoadedEvent {\n durationMs: number\n fromCache: boolean\n hasPublished: boolean\n hasDraft: boolean\n hasVersion: boolean\n}\n\n/** @internal */\nexport interface MutationPerformanceEvent {\n transactionId: string\n debounceMs: number\n apiMs: number\n callbackMs: number\n shard?: string\n}\n\n/** @internal */\nexport interface DocumentRebaseTelemetryEvent {\n remoteMutationCount: number\n localMutationCount: number\n}\n\n/** @internal */\nexport interface DocumentStoreExtraOptions {\n tag?: string\n\n /**\n * Optional handler for failures of the initial document snapshot fetch —\n * the only request delegated here. Commit failures are routed through the\n * commit request's own failure/cancel channels, and listener drops\n * recover via reconnects. When omitted, fetch failures propagate to the\n * document event streams.\n */\n snapshotFetchErrorHandler?: StoreRequestErrorHandler\n\n /**\n * Called when we recover from sync error\n * Meant for error tracking / telemetry purposes\n * @param error - the {@link OutOfSyncError} recovered from\n */\n onSyncErrorRecovery?(error: OutOfSyncError): void\n onReportLatency?: (event: LatencyReportEvent) => void\n onSlowCommit?: () => void\n onDocumentPairLoaded?: (event: DocumentPairLoadedEvent) => void\n onReportMutationPerformance?: (event: MutationPerformanceEvent) => void\n onDocumentRebase?: (event: DocumentRebaseTelemetryEvent) => void\n}\n\n/** @internal */\nexport type ListenerEvent =\n | MutationEvent\n | ReconnectEvent\n | InitialSnapshotEvent\n | PendingMutationsEvent\n | WelcomeEvent\n | WelcomeBackEvent\n | ResetEvent\n\nconst PENDING_START: PendingMutationsEvent = {type: 'pending', phase: 'begin'}\nconst PENDING_END: PendingMutationsEvent = {type: 'pending', phase: 'end'}\n\nfunction isMutationEvent(msg: ListenerEvent): msg is MutationEvent {\n return msg.type === 'mutation'\n}\nfunction isMultiTransactionEvent(msg: MutationEvent) {\n return msg.transactionTotalEvents > 1\n}\n\nfunction allPendingTransactionEventsReceived(listenerEvents: ListenerEvent[]) {\n const groupedMutations = groupBy(\n listenerEvents.filter((ev): ev is MutationEvent => ev.type === 'mutation'),\n (e) => e.transactionId,\n )\n // Note: we can't assume that the events come in order, so instead of checking the counter attributes we check that we have actually received all\n return Object.values(groupedMutations).every(\n (mutations) => mutations.length === mutations[0].transactionTotalEvents,\n )\n}\n\n/** @internal */\nexport function getPairListener(\n _client: SanityClient,\n idPair: IdPair,\n options: DocumentStoreExtraOptions = {},\n): Observable<ListenerEvent> {\n const {publishedId, draftId, versionId} = idPair\n const client = idPair.versionId ? _client.withConfig(RELEASES_STUDIO_CLIENT_OPTIONS) : _client\n if (\n (idPair.versionId && getVersionFromId(idPair.versionId) === 'published') ||\n (idPair.versionId && getVersionFromId(idPair.versionId) === 'drafts')\n ) {\n throw new Error('VersionId cannot be \"published\" or \"drafts\"')\n }\n const sharedEvents = defer(() =>\n (\n client.observable.listen(\n `*[_id in $ids]`,\n {\n ids: [publishedId, draftId, versionId].filter((id) => typeof id !== 'undefined'),\n },\n {\n includeResult: false,\n includeAllVersions: true,\n enableResume: true,\n events: ['welcome', 'mutation', 'reconnect', 'reset', 'welcomeback'],\n effectFormat: 'mendoza',\n tag: options.tag || 'document.pair.listen',\n },\n ) as Observable<WelcomeEvent | MutationEvent | ReconnectEvent | WelcomeBackEvent | ResetEvent>\n ).pipe(\n dedupeListenerEvents(),\n map((event): WelcomeEvent | MutationEvent | ReconnectEvent | WelcomeBackEvent | ResetEvent =>\n event.type === 'mutation'\n ? {\n ...event,\n // client equivalent of `event.messageDispatchedAt`\n // note: consider moving this to client.listen()\n messageReceivedAt: new Date().toString(),\n }\n : event,\n ),\n shareReplayLatest({\n predicate: (event) =>\n event.type === 'welcome' ||\n event.type === 'reconnect' ||\n event.type === 'reset' ||\n event.type === 'welcomeback',\n }),\n ),\n )\n\n const pairEvents$ = sharedEvents.pipe(\n concatMap((event) => {\n const shouldSyncDocument =\n event.type === 'reset' ||\n // note: resumability may not be enabled – if so, treat welcome the same way as a reset\n event.type === 'welcome'\n return shouldSyncDocument\n ? fetchInitialDocumentSnapshots().pipe(\n mergeMap(({draft, published, version}) => [\n createSnapshotEvent(draftId, draft),\n createSnapshotEvent(publishedId, published),\n ...(versionId ? [createSnapshotEvent(versionId, version)] : []),\n ]),\n )\n : of(event)\n }),\n scan(\n (\n acc: {\n next: (InitialSnapshotEvent | ListenerEvent | WelcomeEvent)[]\n buffer: (InitialSnapshotEvent | ListenerEvent | WelcomeEvent)[]\n },\n msg,\n ) => {\n // we only care about mutation events\n if (!isMutationEvent(msg)) {\n return {next: [msg], buffer: []}\n }\n\n const isBuffering = acc.buffer.length > 0\n const isMulti = isMultiTransactionEvent(msg)\n if (!isMulti && !isBuffering) {\n // simple case, we have no buffer, and the event is a single-transaction event, so just pass it on\n return {next: [msg], buffer: []}\n }\n\n if (!isMulti) {\n // we have received a single transaction event while waiting for the rest of events from a multi transaction\n // put it in the buffer\n return {next: [], buffer: acc.buffer.concat(msg)}\n }\n\n const nextBuffer = acc.buffer.concat(msg)\n if (allPendingTransactionEventsReceived(nextBuffer)) {\n // we have received all pending transactions, emit the buffer, and signal end of buffer\n return {next: nextBuffer.concat(PENDING_END), buffer: []}\n }\n // if we get here, we are still waiting for more multi-transaction messages\n // if nextBuffer only has one element, we know we just started buffering\n return {next: nextBuffer.length === 1 ? [PENDING_START] : [], buffer: nextBuffer}\n },\n {next: [], buffer: []},\n ),\n // note: this flattens the array, and in the case of an empty array, no event will be pushed downstream\n mergeMap((v) => v.next),\n share(),\n )\n\n const draftEvents$ = pairEvents$.pipe(\n filter((event) =>\n event.type === 'mutation' || event.type === 'snapshot' ? event.documentId === draftId : true,\n ),\n sequentializeListenerEvents(),\n )\n\n const publishedEvents$ = pairEvents$.pipe(\n filter((event) =>\n event.type === 'mutation' || event.type === 'snapshot'\n ? event.documentId === publishedId\n : true,\n ),\n sequentializeListenerEvents(),\n )\n\n const versionEvents$ = pairEvents$.pipe(\n filter((event) =>\n event.type === 'mutation' || event.type === 'snapshot'\n ? event.documentId === versionId\n : true,\n ),\n sequentializeListenerEvents(),\n )\n\n return merge(draftEvents$, publishedEvents$, versionEvents$).pipe(\n catchError((err, caught$) => {\n if (err instanceof OutOfSyncError) {\n debug('Recovering from OutOfSyncError: %s', err.name)\n if (typeof options?.onSyncErrorRecovery === 'function') {\n options?.onSyncErrorRecovery(err)\n } else {\n console.error(err)\n }\n // this will retry immediately\n return caught$\n }\n\n // A listener 401 is a dead session (see isConnectionSessionError), so\n // complete the stream rather than rethrow — an errored stream is rethrown\n // by `useSyncObservable` during render and crashes the tool. Forced logout\n // is not triggered here; it's owned by the request handler, which 401s on\n // the ordinary HTTP requests a mounted pane also fires (users, grants, …).\n // The pane keeps its last value (or stays loading if it never got a\n // snapshot) until that logout lands.\n if (isConnectionSessionError(err)) {\n debug('Listener connection rejected (HTTP 401), terminating (invalid session)')\n return EMPTY\n }\n\n return throwError(() => err)\n }),\n )\n\n function fetchInitialDocumentSnapshots(): Observable<Snapshots> {\n const fetchDocuments = () =>\n client.observable.getDocuments<SanityDocument>(\n [publishedId, draftId, versionId].filter((id): id is string => typeof id === 'string'),\n {tag: 'document.pair.fetch'},\n )\n\n // The pair cannot load without these snapshots, and there is no local\n // recovery if the fetch fails — delegate failures to the error handler\n // when one is provided. Retryable: it's an idempotent GET, safe to\n // re-run.\n //\n // While the handler holds a failed fetch for re-run, `pairEvents$`\n // buffers subsequent listener events behind this observable (concatMap)\n // on purpose: they must chain onto the snapshot once it arrives.\n // The buffer stays small — the listener only carries events for this\n // pair's documents — and tearing down the pair drops it.\n return defer(() =>\n options.snapshotFetchErrorHandler\n ? options.snapshotFetchErrorHandler.attempt(fetchDocuments, {retryable: true})\n : fetchDocuments(),\n ).pipe(\n map(([published, draft, version]) => ({\n draft,\n published,\n version,\n })),\n )\n }\n}\n\nfunction createSnapshotEvent(\n documentId: string,\n document: null | SanityDocument,\n): InitialSnapshotEvent {\n return {\n type: 'snapshot',\n documentId,\n document,\n }\n}\n","import {type SanityClient} from '@sanity/client'\n\nimport {RELEASES_STUDIO_CLIENT_OPTIONS} from '../../../../releases/util/releasesClient'\nimport {type IdPair} from '../../types'\n\nconst ACTIONS_API_MINIMUM_VERSION = '2025-02-19'\n\nexport function actionsApiClient(client: SanityClient, idPair: IdPair): SanityClient {\n if (idPair.versionId) {\n // TODO: Remove after API version is stable and support releases\n return client.withConfig(RELEASES_STUDIO_CLIENT_OPTIONS)\n }\n return client.withConfig({\n apiVersion: ACTIONS_API_MINIMUM_VERSION,\n })\n}\n","import {type SanityClient} from '@sanity/client'\n\nimport {RELEASES_STUDIO_CLIENT_OPTIONS} from '../../../../releases/util/releasesClient'\nimport {type IdPair} from '../../types'\n\nexport function operationsApiClient(client: SanityClient, idPair: IdPair): SanityClient {\n if (idPair.versionId) {\n // TODO: Remove after API version is stable and support releases\n return client.withConfig(RELEASES_STUDIO_CLIENT_OPTIONS)\n }\n return client\n}\n","import {\n type Action,\n type MultipleActionResult,\n type SanityClient,\n type SingleMutationResult,\n} from '@sanity/client'\nimport {type Mutation} from '@sanity/mutator'\nimport {type SanityDocument, type SanityDocumentLike} from '@sanity/types'\nimport omit from 'lodash-es/omit.js'\nimport {combineLatest, defer, EMPTY, from, merge, type Observable, of, timer} from 'rxjs'\nimport {\n catchError,\n distinctUntilChanged,\n filter,\n map,\n mergeMap,\n scan,\n share,\n shareReplay,\n startWith,\n switchMap,\n takeUntil,\n tap,\n withLatestFrom,\n} from 'rxjs/operators'\n\nimport {isInvalidSessionError} from '../../../util/apiErrors'\nimport {type DocumentVariantType} from '../../../util/getDocumentVariantType'\nimport {getVariantId} from '../../../variants/tool/util'\nimport {\n type BufferedDocumentEvent,\n createBufferedDocument,\n} from '../buffered-doc/createBufferedDocument'\nimport {type CommitRequest} from '../buffered-doc/createObservableBufferedDocument'\nimport {\n type DocumentRebaseEvent,\n type MutationPayload,\n type RemoteSnapshotEvent,\n} from '../buffered-doc/types'\nimport {\n type DocumentStoreExtraOptions,\n getPairListener,\n type InitialSnapshotEvent,\n type LatencyReportEvent,\n type ListenerEvent,\n type MutationPerformanceEvent,\n} from '../getPairListener'\nimport {\n type IdPair,\n type MutationEvent,\n type PendingMutationsEvent,\n type ReconnectEvent,\n type ResetEvent,\n type WelcomeBackEvent,\n type WelcomeEvent,\n} from '../types'\nimport {actionsApiClient} from './utils/actionsApiClient'\nimport {operationsApiClient} from './utils/operationsApiClient'\n\n/** Timeout on request that fetches shard name before reporting latency */\nconst FETCH_SHARD_TIMEOUT = 20_000\n\n/** TTL for unmatched entries in the latency tracking pending array */\nconst PENDING_ENTRY_TTL = 60_000\n\n/** Duration after which a commit is considered slow and a warning is surfaced to the user */\nconst SLOW_COMMIT_TIMEOUT_MS = 50_000\n\nconst isMutationEventForDocId =\n (id: string) =>\n (event: ListenerEvent): event is MutationEvent | InitialSnapshotEvent => {\n return (event.type === 'snapshot' || event.type === 'mutation') && event.documentId === id\n }\n\n/**\n * @hidden\n * @beta */\nexport type WithVersion<T> = T & {version: DocumentVariantType}\n\n/**\n * @hidden\n * @beta */\nexport type DocumentVersionEvent = WithVersion<\n ReconnectEvent | BufferedDocumentEvent | WelcomeEvent | WelcomeBackEvent | ResetEvent\n>\n\n/**\n * @hidden\n * @beta */\nexport type RemoteSnapshotVersionEvent = WithVersion<RemoteSnapshotEvent>\n\n/**\n * @hidden\n * @beta\n * The SingleMutationResult type from `@sanity/client` doesn't reflect what we get back from POST /mutate\n */\nexport type MutationResult = Omit<SingleMutationResult, 'documentId'>\n\n/**\n * @hidden\n * @beta */\nexport interface DocumentVersion {\n consistency$: Observable<boolean>\n remoteSnapshot$: Observable<RemoteSnapshotVersionEvent>\n events: Observable<DocumentVersionEvent>\n\n patch: (patches: any[]) => MutationPayload[]\n create: (document: Partial<SanityDocument>) => MutationPayload\n createIfNotExists: (document: SanityDocument) => MutationPayload\n createOrReplace: (document: SanityDocument) => MutationPayload\n delete: () => MutationPayload\n\n mutate: (mutations: MutationPayload[]) => void\n commit: () => void\n}\n\n/**\n * The error thrown by the most recent failed commit attempt. Wrapped in an\n * object (rather than emitted raw) because a commit can reject with any\n * thrown value — including `undefined`, which would otherwise be\n * indistinguishable from the healthy state.\n *\n * @internal\n */\nexport type CommitError = {error: unknown}\n\n/**\n * @hidden\n * @beta */\nexport type Pair = {\n /** @internal */\n transactionsPendingEvents$: Observable<PendingMutationsEvent>\n /**\n * The error from the most recent commit attempt while it failed and is\n * being retried by the mutator, or `undefined` while commits are healthy.\n * Resets to `undefined` on the next successful (or terminally cancelled)\n * commit, and when the pair returns to a consistent state — i.e. the\n * buffered edits the failure was about no longer exist. Distinguishes\n * \"commits are failing\" from \"the backlog is merely slow\" — see\n * `useDocumentSyncState`.\n * @internal\n */\n commitError$: Observable<CommitError | undefined>\n published: DocumentVersion\n draft: DocumentVersion\n version?: DocumentVersion\n}\n\nfunction setVersion<T>(version: 'draft' | 'published' | 'version') {\n return (ev: T): T & {version: 'draft' | 'published' | 'version'} => ({...ev, version})\n}\n\nfunction requireId<T extends {_id?: string; _type: string}>(\n value: T,\n): asserts value is T & {_id: string} {\n if (!value._id) {\n throw new Error('Expected document to have an _id')\n }\n}\n\n//if we're patching a published document directly\n//then we're live editing and we should use raw mutations\n//rather than actions\nfunction isLiveEditMutation(mutationParams: Mutation['params'], publishedId: string) {\n const {resultRev, ...mutation} = mutationParams\n const patchTargets: string[] = mutation.mutations.flatMap((mut) => {\n const mutationPayloads = Object.values(mut)\n if (mutationPayloads.length > 1) {\n throw new Error('Did not expect multiple mutations in the same payload')\n }\n return mutationPayloads[0].id || mutationPayloads[0]._id\n })\n return patchTargets.every((target) => target === publishedId)\n}\n\nfunction toActions(idPair: IdPair, mutationParams: Mutation['params']): Action[] {\n const actions = mutationParams.mutations.flatMap<Action>((mutations) => {\n // This action is not always interoperable with the equivalent mutation. It will fail if the\n // published version of the document already exists.\n if (mutations.createIfNotExists) {\n // ignore all createIfNotExists, as these should be covered by the actions api and only be done locally\n return []\n }\n if (mutations.create) {\n // the actions API requires attributes._id to be set, while it's optional in the mutation API\n requireId(mutations.create)\n const createSystem = (mutations.create as SanityDocumentLike)._system\n if (mutations.create._id === idPair.versionId && createSystem?.variant) {\n return {\n actionType: 'sanity.action.document.variant.create',\n publishedId: idPair.publishedId,\n variantId: getVariantId(createSystem.variant._ref),\n document: mutations.create,\n bundleId: createSystem.bundleId,\n }\n }\n return {\n actionType: 'sanity.action.document.create',\n publishedId: idPair.publishedId,\n attributes: mutations.create,\n ifExists: 'fail',\n }\n }\n if (mutations.patch) {\n return {\n actionType: 'sanity.action.document.edit',\n draftId: idPair.versionId ?? idPair.draftId,\n publishedId: idPair.publishedId,\n patch: omit(mutations.patch, 'id'),\n }\n }\n throw new Error('Cannot map mutation to action')\n })\n\n // Empty action invocations are a noop; although Content Lake accepts them, no transaction will\n // be executed, causing Studio to become stuck in a pending state. To prevent this occurring, a\n // fake unset mutation is added whenever an empty set of actions would otherwise be executed.\n if (actions.length === 0) {\n return [\n {\n actionType: 'sanity.action.document.edit',\n draftId: idPair.draftId,\n publishedId: idPair.publishedId,\n patch: {\n unset: ['_empty_action_guard_pseudo_field_'],\n },\n },\n ]\n }\n\n return actions\n}\n\nfunction commitActions(client: SanityClient, idPair: IdPair, mutationParams: Mutation['params']) {\n if (isLiveEditMutation(mutationParams, idPair.publishedId)) {\n return commitMutations(client, idPair, mutationParams)\n }\n\n return actionsApiClient(client, idPair).observable.action(toActions(idPair, mutationParams), {\n tag: 'document.commit',\n transactionId: mutationParams.transactionId,\n })\n}\n\nfunction commitMutations(\n client: SanityClient,\n idPair: IdPair,\n mutationParams: Mutation['params'],\n): Promise<MutationResult> {\n const {resultRev, ...mutation} = mutationParams\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n return operationsApiClient(client, idPair).dataRequest('mutate', mutation, {\n visibility: 'async',\n returnDocuments: false,\n tag: 'document.commit',\n // This makes sure the studio doesn't crash when a draft is crated\n // because someone deleted a referenced document in the target dataset\n skipCrossDatasetReferenceValidation: true,\n })\n}\n\n/**\n * The 4xx statuses we positively know are terminal for a commit: resubmitting\n * the same mutation can never succeed, so the buffered edits are cancelled\n * (rejected + reset to server HEAD) instead of retried. Opt-in by explicit\n * status rather than a blanket 4xx rule, because the buckets have opposite\n * failure modes: wrongly retrying a terminal error leaves the document\n * visibly stalled with the edits preserved (recoverable), while wrongly\n * cancelling a transient error silently destroys the user's work. Statuses\n * not listed here — including transient 4xx like 408/429 and any 4xx we\n * haven't classified — take the conservative retry path.\n *\n * 401 is terminal only for resource-level denials (e.g. a missing grant —\n * some endpoints answer those with 401, not 403). A 401 tagged as an invalid\n * session (`SIO-401-AEX` expired, `SIO-401-ANF` not found) is carved out\n * below: it says nothing about the mutation itself, and re-authenticating\n * can make the retry succeed, so the buffered edits must be preserved\n * rather than wiped mid-edit. The session itself is handled separately by\n * the force-logout flow.\n */\nconst TERMINAL_COMMIT_STATUSES = new Set([400, 401, 402, 403, 404, 409, 410, 412, 413, 422])\n\n/**\n * The result of a single commit attempt. Failures are routed to the mutator\n * (`request.failure` → retry with backoff, `request.cancel` → terminal\n * reset) *before* being emitted here, so this stream doubles as a\n * side-channel for observing commit health without erroring the document\n * event streams.\n */\ntype CommitAttemptResult =\n | {\n type: 'success'\n result: (MultipleActionResult | MutationResult) & {_perfTimings?: PerfTimings}\n }\n | {type: 'failure'; error: unknown}\n | {type: 'cancel'; error: unknown}\n\nfunction submitCommitRequest(\n client: SanityClient,\n idPair: IdPair,\n request: CommitRequest,\n): Observable<CommitAttemptResult> {\n return from(commitActions(client, idPair, request.mutation.params)).pipe(\n tap({\n next: () => request.success(),\n }),\n map((result): CommitAttemptResult => ({type: 'success', result})),\n // A failed commit is reported to the mutator via `request.cancel` /\n // `request.failure` (which rejects the corresponding commit promise so\n // the buffered document can retry/rebase on reconnect). After that, we\n // must NOT let the error propagate down this observable: it feeds\n // `commits$` → `combinedEvents` → the document `events` stream, and an\n // errored events stream is rethrown by `useObservable` (react-rx) when\n // `useEditState` reads it during render, crashing the document pane.\n // Emit the attempt result as a value instead — the failure has already\n // been routed through its proper channel.\n catchError((error) => {\n // A known-terminal client error cancels: the buffered mutations can't\n // succeed by retrying, so the commit is rejected and the buffer reset\n // to server HEAD (see TERMINAL_COMMIT_STATUSES for the rationale).\n // Everything else — 5xx, transient 4xx (408/429), unclassified 4xx,\n // session-expiry 401s, network errors — fails, so the mutator keeps\n // the buffer and retries with backoff.\n // `error` can be any thrown value — guard before using `in`, which\n // throws on primitives.\n const statusCode =\n typeof error === 'object' &&\n error !== null &&\n 'statusCode' in error &&\n typeof error.statusCode === 'number'\n ? error.statusCode\n : undefined\n if (\n statusCode !== undefined &&\n TERMINAL_COMMIT_STATUSES.has(statusCode) &&\n !isInvalidSessionError(error)\n ) {\n request.cancel(error)\n return of<CommitAttemptResult>({type: 'cancel', error})\n }\n request.failure(error)\n return of<CommitAttemptResult>({type: 'failure', error})\n }),\n )\n}\n\ntype PerfTimings = {\n firstMutationReceivedAt?: number\n apiRequestSentAt: number\n apiResponseReceivedAt: number\n}\n\ntype LatencyTrackingEvent = {\n transactionId: string\n submittedAt: Date\n receivedAt: Date\n deltaMs: number\n perfTimings?: PerfTimings\n}\n\ntype LatencyTrackingPendingEntry =\n | {type: 'submit'; transactionId: string; timestamp: Date; perfTimings?: PerfTimings}\n | {type: 'receive'; transactionId: string; timestamp: Date}\n\ntype LatencyTrackingEntry = LatencyTrackingPendingEntry | {type: 'reset'}\n\ntype LatencyTrackingState = {\n pending: LatencyTrackingPendingEntry[]\n event: LatencyTrackingEvent | undefined\n}\n\n/** @internal */\nexport function checkoutPair(\n client: SanityClient,\n idPair: IdPair,\n /**\n * @deprecated does nothing Preserved to avoid breaking changes\n * Will be removed in the next major version.\n */\n _serverActionsEnabled: Observable<boolean> | undefined,\n options: DocumentStoreExtraOptions = {},\n): Pair {\n const {publishedId, draftId, versionId} = idPair\n\n const {\n onReportLatency,\n onSyncErrorRecovery,\n onSlowCommit,\n onReportMutationPerformance,\n onDocumentRebase,\n snapshotFetchErrorHandler,\n tag,\n } = options\n\n const listenerEvents$ = getPairListener(client, idPair, {\n onSyncErrorRecovery,\n tag,\n snapshotFetchErrorHandler,\n }).pipe(share())\n\n const connectionChangeEvents$ = listenerEvents$.pipe(\n filter((ev) => ev.type === 'reconnect' || ev.type === 'welcome' || ev.type === 'welcomeback'),\n )\n\n const draft = createBufferedDocument(\n draftId,\n listenerEvents$.pipe(filter(isMutationEventForDocId(draftId))),\n )\n\n const version =\n typeof versionId === 'undefined'\n ? undefined\n : createBufferedDocument(\n versionId,\n listenerEvents$.pipe(filter(isMutationEventForDocId(versionId))),\n )\n\n const published = createBufferedDocument(\n publishedId,\n listenerEvents$.pipe(filter(isMutationEventForDocId(publishedId))),\n )\n\n // share commit handling between draft and published\n const transactionsPendingEvents$ = listenerEvents$.pipe(\n filter((ev): ev is PendingMutationsEvent => ev.type === 'pending'),\n )\n\n const commitRequests$ = merge(\n draft.commitRequest$,\n published.commitRequest$,\n version ? version.commitRequest$ : EMPTY,\n ).pipe(share())\n\n const commitAttemptResults$ = commitRequests$.pipe(\n mergeMap((commitRequest) => {\n const apiRequestSentAt = Date.now()\n return submitCommitRequest(client, idPair, commitRequest).pipe(\n map((attemptResult): CommitAttemptResult =>\n attemptResult.type === 'success'\n ? {\n ...attemptResult,\n result: {\n ...attemptResult.result,\n _perfTimings: {\n firstMutationReceivedAt: commitRequest.firstMutationReceivedAt,\n apiRequestSentAt,\n apiResponseReceivedAt: Date.now(),\n },\n },\n }\n : attemptResult,\n ),\n )\n }),\n share(),\n )\n\n // The successful commits — failures/cancels have already been routed to the\n // mutator and must not reach the document event streams (see\n // `submitCommitRequest`).\n const commits$ = commitAttemptResults$.pipe(\n filter(\n (attemptResult): attemptResult is Extract<CommitAttemptResult, {type: 'success'}> =>\n attemptResult.type === 'success',\n ),\n map((attemptResult) => attemptResult.result),\n share(),\n )\n\n // Whether every buffered document in the pair is free of pending local\n // mutations — the pair-level version of the per-document `consistency$`.\n const consistent$ = combineLatest([\n draft.consistency$,\n published.consistency$,\n version ? version.consistency$ : of(true),\n ]).pipe(\n map((states) => states.every(Boolean)),\n distinctUntilChanged(),\n )\n\n // The error from the most recent commit attempt while the mutator is\n // retrying it on backoff, `undefined` while commits are healthy. Multicast\n // with replay so late subscribers (the sync-state hook mounts after the\n // pair is checked out) see the current value, not just future attempt\n // results — the silenced merge into `combinedEvents` below keeps it\n // recording for the pair's lifetime.\n const commitError$ = merge(\n commitAttemptResults$.pipe(\n map((attemptResult): CommitError | undefined =>\n attemptResult.type === 'failure' ? {error: attemptResult.error} : undefined,\n ),\n ),\n // Returning to consistency means the buffered edits the failure was\n // about are gone — drained, discarded, or reset to server HEAD by a\n // fresh snapshot — so nothing is being retried anymore. Note this is\n // deliberately NOT keyed on listener reconnects (welcome/welcome-back):\n // a live listener says nothing about commit health, and a reconnect\n // while still unsynced must not mask an ongoing failure.\n consistent$.pipe(\n filter((isConsistent) => isConsistent),\n map(() => undefined),\n ),\n ).pipe(startWith(undefined), distinctUntilChanged(), shareReplay({bufferSize: 1, refCount: true}))\n\n const pendingEnd$ = transactionsPendingEvents$.pipe(filter((ev) => ev.phase === 'end'))\n const commitResolved$ = merge(pendingEnd$, commits$)\n\n // Each new commit request restarts the timer via switchMap.\n // The timer is cancelled when the commit succeeds or pending mutations resolve.\n // Note: a *failed* commit does not emit on `commits$` (failures are filtered\n // out of `commitAttemptResults$` above), so `commitResolved$` does not fire for\n // it — a commit that fails after SLOW_COMMIT_TIMEOUT_MS still triggers\n // `onSlowCommit`. That's intentional: it was slow, and it's now failing.\n const slowCommitWarning$ = onSlowCommit\n ? commitRequests$.pipe(\n switchMap(() => timer(SLOW_COMMIT_TIMEOUT_MS).pipe(takeUntil(commitResolved$))),\n tap(() => onSlowCommit()),\n )\n : EMPTY\n\n const rebaseEvents$ = onDocumentRebase\n ? merge(draft.events, published.events, ...(version ? [version.events] : [])).pipe(\n filter((ev): ev is DocumentRebaseEvent & {type: 'rebase'} => ev.type === 'rebase'),\n tap((ev) => {\n try {\n onDocumentRebase({\n remoteMutationCount: ev.remoteMutations.length,\n localMutationCount: ev.localMutations.length,\n })\n } catch {\n // Telemetry callbacks must never kill the document pipeline\n }\n }),\n )\n : EMPTY\n\n // Note: we're only subscribing to this for the side-effect\n const combinedEvents = defer(() =>\n merge(\n onReportLatency || onReportMutationPerformance\n ? reportLatency({\n commits$: commits$,\n listenerEvents$: listenerEvents$,\n client,\n onReportLatency,\n onReportMutationPerformance,\n })\n : merge(commits$, listenerEvents$),\n slowCommitWarning$,\n rebaseEvents$,\n commitError$,\n ),\n ).pipe(\n mergeMap(() => EMPTY),\n share(),\n )\n\n return {\n transactionsPendingEvents$,\n commitError$,\n draft: {\n ...draft,\n events: merge(combinedEvents, connectionChangeEvents$, draft.events).pipe(\n map(setVersion('draft')),\n ),\n remoteSnapshot$: draft.remoteSnapshot$.pipe(map(setVersion('draft'))),\n },\n ...(typeof version === 'undefined'\n ? {}\n : {\n version: {\n ...version,\n events: merge(combinedEvents, connectionChangeEvents$, version.events).pipe(\n map(setVersion('version')),\n ),\n remoteSnapshot$: version.remoteSnapshot$.pipe(map(setVersion('version'))),\n },\n }),\n published: {\n ...published,\n events: merge(combinedEvents, connectionChangeEvents$, published.events).pipe(\n map(setVersion('published')),\n ),\n remoteSnapshot$: published.remoteSnapshot$.pipe(map(setVersion('published'))),\n },\n }\n}\n\nfunction reportLatency(options: {\n commits$: Observable<(MultipleActionResult | MutationResult) & {_perfTimings?: PerfTimings}>\n listenerEvents$: Observable<ListenerEvent>\n client: SanityClient\n onReportLatency?: (event: LatencyReportEvent) => void\n onReportMutationPerformance?: (event: MutationPerformanceEvent) => void\n}) {\n const {client, commits$, listenerEvents$, onReportLatency, onReportMutationPerformance} = options\n // Note: this request happens once and the result is then cached indefinitely\n let shardInfo: Promise<string | undefined>\n try {\n shardInfo = fetch(client.getUrl(client.getDataUrl('ping')), {\n signal: AbortSignal.timeout(FETCH_SHARD_TIMEOUT),\n })\n .then(async (response) => {\n const shard = response.headers.get('X-Sanity-Shard') || undefined\n\n // The ping response is tiny; consuming it lets the browser finish the\n // H2/H3 stream cleanly and avoids long pending receive/cancel timing.\n await response.arrayBuffer().catch(() => undefined)\n return shard\n })\n .catch(() => undefined)\n } catch {\n shardInfo = Promise.resolve(undefined)\n }\n\n const submittedMutations = commits$.pipe(\n map((ev): LatencyTrackingEntry => ({\n type: 'submit' as const,\n transactionId: ev.transactionId,\n timestamp: new Date(),\n perfTimings: ev._perfTimings,\n })),\n share(),\n )\n\n const receivedMutations = listenerEvents$.pipe(\n filter((ev) => ev.type === 'mutation'),\n map((ev): LatencyTrackingEntry => ({\n type: 'receive' as const,\n transactionId: ev.transactionId,\n timestamp: new Date(),\n })),\n share(),\n )\n\n // Clear pending entries on reconnection to avoid matching stale pre-reconnect\n // submit entries with post-reconnect listener events (which would produce\n // wildly inaccurate latency measurements).\n const reconnectionResets = listenerEvents$.pipe(\n filter((ev) => ev.type === 'reconnect' || ev.type === 'welcome' || ev.type === 'welcomeback'),\n map((): LatencyTrackingEntry => ({type: 'reset'})),\n )\n\n return merge(submittedMutations, receivedMutations, reconnectionResets).pipe(\n scan(\n (state: LatencyTrackingState, event): LatencyTrackingState => {\n if (event.type === 'reset') {\n return {event: undefined, pending: []}\n }\n\n // Evict stale entries to prevent unbounded growth from remote/duplicate mutations\n const now = Date.now()\n const pending = state.pending.filter((e) => now - e.timestamp.getTime() < PENDING_ENTRY_TTL)\n\n const matchingIndex = pending.findIndex(\n (e) => e.transactionId === event.transactionId && e.type !== event.type,\n )\n if (matchingIndex > -1) {\n const matching = pending[matchingIndex]\n const [submitEvent, receiveEvent] =\n matching.type === 'submit' ? [matching, event] : [event, matching]\n return {\n event: {\n transactionId: event.transactionId,\n submittedAt: submitEvent.timestamp,\n receivedAt: receiveEvent.timestamp,\n deltaMs: receiveEvent.timestamp.getTime() - submitEvent.timestamp.getTime(),\n perfTimings: submitEvent.type === 'submit' ? submitEvent.perfTimings : undefined,\n },\n // Remove the matched entry and any other entries with the same transactionId\n // (e.g., duplicate receive events from multi-document transactions)\n pending: pending.filter(\n (e, i) => i !== matchingIndex && e.transactionId !== event.transactionId,\n ),\n }\n }\n return {event: undefined, pending: pending.concat(event)}\n },\n {event: undefined, pending: []},\n ),\n map((state) => state.event),\n filter((event) => !!event),\n withLatestFrom(from(shardInfo).pipe(startWith(undefined))),\n tap(([event, shard]) => {\n try {\n onReportLatency?.({latencyMs: event.deltaMs, shard, transactionId: event.transactionId})\n } catch {\n // Telemetry callbacks must never kill the document pipeline\n }\n\n if (onReportMutationPerformance && event.perfTimings) {\n const {firstMutationReceivedAt, apiRequestSentAt, apiResponseReceivedAt} = event.perfTimings\n const listenerReceivedAt = event.receivedAt.getTime()\n\n if (firstMutationReceivedAt !== undefined) {\n try {\n onReportMutationPerformance({\n transactionId: event.transactionId,\n debounceMs: Math.max(0, apiRequestSentAt - firstMutationReceivedAt),\n apiMs: Math.max(0, apiResponseReceivedAt - apiRequestSentAt),\n // Listener and API response race each other — both are triggered\n // server-side after the mutation is committed. Measure callback from\n // when the request was sent, not when the HTTP response arrived.\n callbackMs: Math.max(0, listenerReceivedAt - apiRequestSentAt),\n shard,\n })\n } catch {\n // Telemetry callbacks must never kill the document pipeline\n }\n }\n }\n }),\n )\n}\n","import {type Observable} from 'rxjs'\n\nexport function memoize<TFunction extends (...args: any[]) => Observable<any>>(\n fn: TFunction,\n keyGen: (...args: Parameters<TFunction>) => string,\n): TFunction {\n const MEMO: {[key: string]: Observable<unknown>} = Object.create(null)\n const memoizedFn = (...args: Parameters<TFunction>): Observable<unknown> => {\n const key = keyGen(...args)\n if (!(key in MEMO)) {\n MEMO[key] = fn(...args)\n }\n return MEMO[key]\n }\n\n return memoizedFn as TFunction\n}\n","import {type SanityClient} from '@sanity/client'\n\n/**\n * Segments identifying the credentialed client an observable is built with:\n * `[token, dataset, projectId]`. Any module-level {@link memoize} of a\n * client-capturing observable MUST include these in its key — keying by\n * project/dataset alone replays a stale-token client after a cross-tab\n * re-login and 401s. Keyed by the token *value* (not the client instance) so\n * sibling clients sharing a token reuse one entry and only a real credential\n * change makes a new one.\n *\n * @internal\n */\nexport function getClientCredentialSegments(client: SanityClient): [string, string, string] {\n const {token, dataset, projectId} = client.config()\n return [token ?? '', dataset ?? '', projectId ?? '']\n}\n\n/**\n * Builds a memo cache key from an ordered list of segments. Segments are joined\n * via `JSON.stringify` rather than a `-` (or any single delimiter): the raw\n * values routinely contain dashes (dataset names like `test-dataset`, document\n * ids, type names), so a plain join lets distinct tuples collide into the same\n * string (`['a-b','c']` and `['a','b-c']` both become `a-b-c`) and reuse the\n * wrong cached observable. The result is an opaque cache key — never parsed or\n * shown to users.\n *\n * @internal\n */\nexport function createMemoKey(segments: readonly (string | undefined)[]): string {\n return JSON.stringify(segments.map((segment) => segment ?? ''))\n}\n","import {type SanityClient} from '@sanity/client'\n\nimport {type IdPair} from '../types'\nimport {createMemoKey, getClientCredentialSegments} from '../utils/memoKey'\n\n// The key must include the credential: the pair captures its client and keeps a\n// listener open, so keying by project/dataset alone would replay a stale-token\n// pair after a re-login and 401 on `/data/listen`. See getClientCredentialSegments.\nexport function memoizeKeyGen(client: SanityClient, idPair: IdPair, typeName: string) {\n return createMemoKey([\n ...getClientCredentialSegments(client),\n idPair.publishedId,\n idPair.versionId,\n typeName,\n ])\n}\n","import {type SanityClient} from '@sanity/client'\nimport {EMPTY, merge, Observable, of, ReplaySubject, share, timer} from 'rxjs'\nimport {mergeMap} from 'rxjs/operators'\n\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {checkoutPair, type Pair} from './checkoutPair'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// How long to keep listener connected for after last unsubscribe.\n// Reduced from 10s to 5s to limit concurrent SSE connections during\n// navigation-heavy sessions. 5s still covers most \"navigate away and back\"\n// patterns while cutting the stale connection window in half.\nconst LISTENER_RESET_DELAY = 5_000\n\nexport const memoizedPair: (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n extraOptions?: DocumentStoreExtraOptions,\n) => Observable<Pair> = memoize(\n (\n client: SanityClient,\n idPair: IdPair,\n _typeName: string,\n pairListenerOptions?: DocumentStoreExtraOptions,\n ): Observable<Pair> => {\n return new Observable<Pair>((subscriber) => {\n const pair = checkoutPair(client, idPair, undefined, pairListenerOptions)\n return merge(\n of(pair),\n // merge in draft, published, and version events to makes sure they receive\n // the events they need for as long as the pair is subscribed to\n pair.draft.events.pipe(mergeMap(() => EMPTY)),\n pair.published.events.pipe(mergeMap(() => EMPTY)),\n pair.version?.events.pipe(mergeMap(() => EMPTY)) ?? EMPTY,\n ).subscribe(subscriber)\n }).pipe(\n share({\n connector: () => new ReplaySubject(1),\n resetOnComplete: true,\n resetOnRefCountZero: () => timer(LISTENER_RESET_DELAY),\n }),\n )\n },\n memoizeKeyGen,\n)\n","import {type SanityClient} from '@sanity/client'\nimport {type Observable} from 'rxjs'\nimport {distinctUntilChanged, shareReplay, switchMap} from 'rxjs/operators'\n\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {type CommitError} from './checkoutPair'\nimport {memoizedPair} from './memoizedPair'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// The error from the most recent commit attempt for the document pair while\n// it failed and is being retried by the mutator, or `undefined` while\n// commits are healthy. Combined with consistency and connection state to\n// distinguish \"commits are failing\" from \"the backlog is merely slow\" — see\n// `useDocumentSyncState`.\nexport const commitErrorStatus: (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n extraOptions?: DocumentStoreExtraOptions,\n) => Observable<CommitError | undefined> = memoize(\n (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n extraOptions?: DocumentStoreExtraOptions,\n ) => {\n return memoizedPair(client, idPair, typeName, extraOptions).pipe(\n switchMap((pair) => pair.commitError$),\n distinctUntilChanged(),\n shareReplay({bufferSize: 1, refCount: true}),\n )\n },\n memoizeKeyGen,\n)\n","import {type SanityClient} from '@sanity/client'\nimport {combineLatest, of, type Observable} from 'rxjs'\nimport {distinctUntilChanged, map, publishReplay, refCount, switchMap} from 'rxjs/operators'\n\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {memoizedPair} from './memoizedPair'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// A stream of all events related to either published or draft, each event comes with a 'target'\n// that specifies which version (draft|published) the event is about\nexport const consistencyStatus: (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n extraOptions?: DocumentStoreExtraOptions,\n) => Observable<boolean> = memoize(\n (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n extraOptions?: DocumentStoreExtraOptions,\n ) => {\n return memoizedPair(client, idPair, typeName, extraOptions).pipe(\n switchMap(({draft, published, version}) =>\n combineLatest([\n draft.consistency$,\n published.consistency$,\n version?.consistency$ ?? of(true),\n ]),\n ),\n map(\n ([draftIsConsistent, publishedIsConsistent, versionIsConsistent]) =>\n draftIsConsistent && publishedIsConsistent && versionIsConsistent,\n ),\n distinctUntilChanged(),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n refCount(),\n )\n },\n memoizeKeyGen,\n)\n","import {type SanityClient} from '@sanity/client'\nimport {EMPTY, merge, type Observable} from 'rxjs'\nimport {switchMap} from 'rxjs/operators'\n\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {type DocumentVersionEvent} from './checkoutPair'\nimport {memoizedPair} from './memoizedPair'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// A stream of all events related to either published or draft, each event comes with a 'target'\n// that specifies which version (draft|published) the event is about\nexport const documentEvents = memoize(\n (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n pairListenerOptions?: DocumentStoreExtraOptions,\n ): Observable<DocumentVersionEvent> => {\n return memoizedPair(client, idPair, typeName, pairListenerOptions).pipe(\n switchMap(({draft, published, version}) =>\n merge(draft.events, published.events, version?.events ?? EMPTY),\n ),\n )\n },\n memoizeKeyGen,\n)\n","import {type SanityClient} from '@sanity/client'\nimport {type SanityDocument} from '@sanity/types'\nimport {type Observable} from 'rxjs'\nimport {filter, map, publishReplay, refCount} from 'rxjs/operators'\n\nimport {type BufferedDocumentEvent} from '../buffered-doc/createBufferedDocument'\nimport {type MutationPayload, type SnapshotEvent} from '../buffered-doc/types'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {\n type IdPair,\n type PendingMutationsEvent,\n type ReconnectEvent,\n type ResetEvent,\n type WelcomeBackEvent,\n type WelcomeEvent,\n} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {type DocumentVersion} from './checkoutPair'\nimport {memoizedPair} from './memoizedPair'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// return true if the event comes with a document snapshot\nfunction isSnapshotEvent(\n event: BufferedDocumentEvent | ReconnectEvent | WelcomeEvent | WelcomeBackEvent | ResetEvent,\n): event is SnapshotEvent & {\n version: 'published' | 'draft'\n} {\n return event.type === 'snapshot'\n}\n\nfunction withSnapshots(pair: DocumentVersion): DocumentVersionSnapshots {\n return {\n snapshots$: pair.events.pipe(\n filter(isSnapshotEvent),\n map((event) => event.document),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n refCount(),\n ),\n\n patch: pair.patch,\n create: pair.create,\n createIfNotExists: pair.createIfNotExists,\n createOrReplace: pair.createOrReplace,\n delete: pair.delete,\n\n mutate: pair.mutate,\n commit: pair.commit,\n }\n}\n\n/** @internal */\nexport interface DocumentVersionSnapshots {\n snapshots$: Observable<SanityDocument>\n\n // helper functions\n patch: (patches: any[]) => MutationPayload[]\n create: (document: any) => MutationPayload\n createIfNotExists: (document: any) => MutationPayload\n createOrReplace: (document: any) => MutationPayload\n delete: () => MutationPayload\n\n mutate: (mutations: MutationPayload[]) => void\n commit: () => void\n}\n\n/** @internal */\ninterface SnapshotPair {\n transactionsPendingEvents$: Observable<PendingMutationsEvent>\n draft: DocumentVersionSnapshots\n published: DocumentVersionSnapshots\n version?: DocumentVersionSnapshots\n}\n\n/** @internal */\nexport const snapshotPair = memoize(\n (\n client: SanityClient,\n idPair: IdPair,\n typeName: string,\n /**\n * @deprecated does nothing\n * Preserved here to avoid breaking changes\n * Will be removed in the next major version.\n */\n _serverActionsEnabled?: Observable<boolean>,\n pairListenerOptions?: DocumentStoreExtraOptions,\n ): Observable<SnapshotPair> => {\n return memoizedPair(client, idPair, typeName, pairListenerOptions).pipe(\n map(({published, draft, version, transactionsPendingEvents$}): SnapshotPair => {\n return {\n transactionsPendingEvents$,\n published: withSnapshots(published),\n draft: withSnapshots(draft),\n ...(version ? {version: withSnapshots(version)} : {}),\n }\n }),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n refCount(),\n )\n },\n memoizeKeyGen,\n)\n","import {type SanityClient} from '@sanity/client'\nimport {type Schema} from '@sanity/types'\nimport {combineLatest, type Observable} from 'rxjs'\nimport {map, publishReplay, refCount, switchMap} from 'rxjs/operators'\n\nimport {type HistoryStore} from '../../history/createHistoryStore'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {memoizeKeyGen} from './memoizeKeyGen'\nimport {type OperationArgs} from './operations/types'\nimport {snapshotPair} from './snapshotPair'\n\nexport const operationArgs = memoize(\n (\n ctx: {\n client: SanityClient\n historyStore: HistoryStore\n schema: Schema\n pairListenerOptions?: DocumentStoreExtraOptions\n },\n idPair: IdPair,\n typeName: string,\n ): Observable<OperationArgs> => {\n return snapshotPair(ctx.client, idPair, typeName, undefined, ctx.pairListenerOptions).pipe(\n switchMap((versions) =>\n combineLatest([\n versions.draft.snapshots$,\n versions.published.snapshots$,\n ...(typeof versions.version === 'undefined' ? [] : [versions.version.snapshots$]),\n ]).pipe(\n map(([draft, published, version]): OperationArgs => ({\n ...ctx,\n idPair,\n typeName,\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n serverActionsEnabled: true,\n snapshots: {\n published,\n draft,\n ...(version\n ? {\n version,\n }\n : {}),\n },\n ...(versions.version\n ? {\n version: versions.version,\n }\n : {}),\n draft: versions.draft,\n published: versions.published,\n })),\n ),\n ),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n refCount(),\n )\n },\n (ctx, idPair, typeName) => {\n return memoizeKeyGen(ctx.client, idPair, typeName)\n },\n)\n","import {type SanityClient} from '@sanity/client'\n\nimport {createMemoKey} from '../utils/memoKey'\n\nexport function getOperationStoreKey(client: SanityClient): string {\n const config = client.config()\n const {projectId, dataset, token} = config\n if (!projectId) {\n throw new Error('Client is missing projectId')\n }\n if (!dataset) {\n throw new Error('Client is missing dataset')\n }\n // Include the token so an operation is routed to the pipeline built on the\n // same credential. This key only needs to agree between the emitter and the\n // pipeline (both call this function) — it does not have to equal the\n // operationEvents memo key. Once operationEvents is memoized per token, a\n // re-login runs a second pipeline; without the token here one emitted\n // operation would match both the fresh and the stale-token pipeline while\n // both are briefly subscribed and execute the mutation twice.\n return createMemoKey([projectId, dataset, token])\n}\n","import {EMPTY} from 'rxjs'\n\nimport {type OperationImpl} from './types'\n\nexport const commit: OperationImpl = {\n disabled: (): false => false,\n execute: ({draft, published, version}) => {\n version?.commit()\n draft.commit()\n published.commit()\n // note: we might be able to connect with the outgoing commit request stream here\n return EMPTY\n },\n}\n","import {type SanityDocument} from '@sanity/types'\n\n/** @internal */\nexport const VARIANT_VERSION_DISABLED = 'VARIANT_VERSION' as const\n\n/** @internal */\nexport type VariantVersionDisabledReason = typeof VARIANT_VERSION_DISABLED\n\n/**\n * Legacy transaction-based operations in `operations/` are not supported for variant-scoped\n * versions. Variant documents route through `serverOperations/` and the variant document actions.\n *\n * @internal\n */\nexport function disabledForVariantVersion(\n version: SanityDocument | null | undefined,\n): VariantVersionDisabledReason | false {\n if (version?._system?.variant?._ref) {\n return VARIANT_VERSION_DISABLED\n }\n return false\n}\n\n/**\n * Corruption tripwire: the base/release document actions must never run against a variant-scoped\n * version. A base publish with a variant version in the `draftId` slot would publish variant\n * content INTO the base published document — data corruption, not a broken button. Operations\n * route variant versions to the variant document actions before reaching the base paths; this\n * assert is insurance that stays correct independently of that routing (e.g. through future\n * refactors or new call sites).\n *\n * @internal\n */\nexport function assertNotVariantVersion(\n version: SanityDocument | null | undefined,\n operationName: string,\n): void {\n if (version?._system?.variant?._ref) {\n throw new Error(\n `Cannot execute the base \"${operationName}\" operation against the variant-scoped version \"${version._id}\": this would write variant content into the base document. This is a bug in the operation routing — please report it.`,\n )\n }\n}\n","import {type Schema} from '@sanity/types'\n\nexport const isLiveEditEnabled = (schema: Schema, typeName: string): boolean =>\n schema.get(typeName)?.liveEdit === true\n","import {\n assertNotVariantVersion,\n disabledForVariantVersion,\n type VariantVersionDisabledReason,\n} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {operationsApiClient} from '../utils/operationsApiClient'\nimport {type OperationImpl} from './types'\n\nexport const del: OperationImpl<[], 'NOTHING_TO_DELETE' | VariantVersionDisabledReason> = {\n disabled: ({snapshots}) => {\n // Legacy transaction delete. Variant-scoped versions are disabled here — use\n // `serverOperations/delete.ts` instead.\n const variantDisabled = disabledForVariantVersion(snapshots?.version)\n if (variantDisabled) {\n return variantDisabled\n }\n return snapshots.draft || snapshots.published ? false : 'NOTHING_TO_DELETE'\n },\n execute: ({client, schema, idPair, typeName, snapshots}) => {\n assertNotVariantVersion(snapshots.version, 'delete')\n const tx = operationsApiClient(client, idPair)\n .observable.transaction()\n .delete(idPair.publishedId)\n\n if (isLiveEditEnabled(schema, typeName)) {\n return tx.commit({tag: 'document.delete'})\n }\n\n return tx.delete(idPair.draftId).commit({\n tag: 'document.delete',\n // this disables referential integrity for cross-dataset references. we\n // have this set because we warn against deletes in the `ConfirmDeleteDialog`\n // UI. This operation is run when \"delete anyway\" is clicked\n skipCrossDatasetReferenceValidation: true,\n })\n },\n}\n","import {\n assertNotVariantVersion,\n disabledForVariantVersion,\n type VariantVersionDisabledReason,\n} from '../utils/assertNotVariantVersion'\nimport {operationsApiClient} from '../utils/operationsApiClient'\nimport {type OperationImpl} from './types'\n\ntype DisabledReason = 'NO_CHANGES' | 'NOT_PUBLISHED' | VariantVersionDisabledReason\n\nexport const discardChanges: OperationImpl<[], DisabledReason> = {\n disabled: ({snapshots}) => {\n // Legacy transaction discard-changes. Variant-scoped versions are disabled here — use\n // `serverOperations/discardChanges.ts` instead.\n const variantDisabled = disabledForVariantVersion(snapshots?.version)\n if (variantDisabled) {\n return variantDisabled\n }\n if (!snapshots.draft) {\n return 'NO_CHANGES'\n }\n if (!snapshots.published) {\n return 'NOT_PUBLISHED'\n }\n return false\n },\n execute: ({client, idPair, snapshots}) => {\n assertNotVariantVersion(snapshots.version, 'discardChanges')\n return operationsApiClient(client, idPair)\n .observable.transaction()\n .delete(idPair.draftId)\n .commit({tag: 'document.discard-changes'})\n },\n}\n","import {type SanityDocument} from '@sanity/types'\n\nimport {getVariantId} from '../tool/util'\n\n/**\n * The routing information of a variant-scoped version document, derived from its `_system`.\n *\n */\nexport interface VariantVersionInfo {\n /** The short variant name (the `_.variants.` prefix stripped from `_system.variant._ref`). */\n variantId: string\n /**\n * The bundle the variant document belongs to: `'drafts'`, a release id, or `'published'` for\n * the variant-of-published document (which carries no `_system.bundleId`).\n */\n bundleId: 'drafts' | 'published' | (string & {})\n}\n\n/**\n * Derives variant routing information from a version document snapshot's `_system`, or\n * `undefined` when the document is not variant-scoped.\n *\n * This is the single discriminator the document operations use to decide between the base and\n * variant action paths. The `_system` field is authoritative and always present on variant\n * documents — only pre-migration non-variant documents may lack it, and those can never be\n * variant-scoped.\n *\n */\nexport function getVariantVersionInfo(\n version: SanityDocument | null | undefined,\n): VariantVersionInfo | undefined {\n const variantRef = version?._system?.variant?._ref\n if (!variantRef) {\n return undefined\n }\n\n return {\n // Strip the `_.variants.` document path prefix to the short variant id. Kept local (instead\n // of `getVariantId` from `variants/tool/util`) to avoid pulling tool-level modules — and\n // their import cycles — into the document store's operations graph.\n variantId: getVariantId(variantRef),\n bundleId: version._system?.bundleId ?? 'published',\n }\n}\n","import {type SanityDocument, type SanityDocumentLike} from '@sanity/types'\nimport omit from 'lodash-es/omit.js'\n\nimport {getDraftId, getVersionFromId, getVersionId} from '../../../../util/draftUtils'\nimport {getVariantVersionInfo} from '../../../../variants/documents/getVariantVersionInfo'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {operationsApiClient} from '../utils/operationsApiClient'\nimport {variantsApiClient} from '../utils/variantsApiClient'\nimport {type MapDocument, type OperationImpl} from './types'\n\n// `_system` is authoritative, server-managed metadata (`group`/`scopeId`/`release`/`variant`\n// references of the SOURCE document): copying it onto the duplicate would attach the new\n// document to the source's group and scope.\nconst omitProps = ['_createdAt', '_updatedAt', '_system']\n\n// Variant create addresses the new document by `(publishedId, variantId, bundleId)`; the\n// server generates the opaque version id. `_rev` is the source revision and must not\n// travel with the payload.\nconst variantOmitProps = [...omitProps, '_id', '_rev']\n\nconst getDocumentToDuplicateId = ({\n versionSnapshot,\n dupeId,\n liveEdit,\n}: {\n versionSnapshot?: SanityDocument | null | undefined\n dupeId: string\n liveEdit: boolean\n}) => {\n // When duplicating a version document we need to create it with a version id.\n // We get the version from the snapshot id and create a new version id for the duplicate.\n // Variant-scoped versions take a different path (`variant.create`) and never reach here.\n if (versionSnapshot) {\n const versionId = getVersionFromId(versionSnapshot._id)\n if (versionId) return getVersionId(dupeId, versionId)\n }\n\n if (liveEdit) {\n return dupeId\n }\n\n return getDraftId(dupeId)\n}\n\nconst mapDocumentNoop: MapDocument = (document) => document\n\nexport const duplicate: OperationImpl<\n [\n baseDocumentId: string,\n options?: {\n mapDocument?: MapDocument\n },\n ],\n 'NOTHING_TO_DUPLICATE'\n> = {\n disabled: ({snapshots}) => {\n return snapshots.published || snapshots.draft || snapshots.version\n ? false\n : 'NOTHING_TO_DUPLICATE'\n },\n execute: (\n {schema, client, snapshots, typeName, idPair},\n dupeId,\n {mapDocument = mapDocumentNoop} = {},\n ) => {\n const source = snapshots.version || snapshots.draft || snapshots.published\n\n if (!source) {\n throw new Error('cannot execute on empty document')\n }\n\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion) {\n // Scope ids are opaque and server-generated: never fabricate\n // `versions.<sourceScope>.<dupeId>`. Address the new document by coordinates\n // and let the action attach variant membership.\n const bundleId = variantVersion.bundleId === 'published' ? undefined : variantVersion.bundleId\n const mapped = mapDocument({\n ...source,\n _id: dupeId,\n _type: source._type,\n })\n\n return variantsApiClient(client).observable.action(\n {\n actionType: 'sanity.action.document.variant.create',\n publishedId: dupeId,\n variantId: variantVersion.variantId,\n ...(bundleId ? {bundleId} : {}),\n document: omit(mapped, variantOmitProps) as SanityDocumentLike,\n },\n {tag: 'document.duplicate'},\n )\n }\n\n const _id = getDocumentToDuplicateId({\n versionSnapshot: snapshots.version,\n dupeId,\n liveEdit: isLiveEditEnabled(schema, typeName),\n })\n\n return operationsApiClient(client, idPair).observable.create(\n omit(\n mapDocument({\n ...source,\n _id,\n _type: source._type,\n }),\n omitProps,\n // Performing `Omit` on a type that has an index signature causes the known properties to\n // be lost.\n ) as SanityDocumentLike,\n {\n tag: 'document.duplicate',\n },\n )\n },\n}\n","import {\n assertNotVariantVersion,\n disabledForVariantVersion,\n type VariantVersionDisabledReason,\n} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {type OperationImpl} from './types'\n\n// todo: we could also consider exposing 'mutate' directly\nexport const patch: OperationImpl<\n [patches: any[], initialDocument?: Record<string, any>],\n VariantVersionDisabledReason\n> = {\n // Legacy local patch. Variant-scoped versions are disabled here — use `serverOperations/patch.ts`\n // instead.\n disabled: ({snapshots}) => disabledForVariantVersion(snapshots?.version),\n execute: (\n {schema, snapshots, idPair, draft, published, version, typeName},\n patches = [],\n initialDocument,\n ): void => {\n assertNotVariantVersion(snapshots.version, 'patch')\n if (version) {\n // No drafting, so patch and commit the version document.\n version.mutate([\n version.createIfNotExists({\n _type: typeName,\n ...initialDocument,\n }),\n ...version.patch(patches),\n ])\n return\n }\n\n if (isLiveEditEnabled(schema, typeName)) {\n // No drafting, so patch and commit the published document\n published.mutate([\n published.createIfNotExists({\n _type: typeName,\n ...initialDocument,\n }),\n ...published.patch(patches),\n ])\n } else {\n draft.mutate([\n draft.createIfNotExists({\n ...initialDocument,\n ...snapshots.published,\n _id: idPair.draftId,\n _type: typeName,\n }),\n ...draft.patch(patches),\n ])\n }\n },\n}\n","import {isReference, type SanityDocument} from '@sanity/types'\nimport omit from 'lodash-es/omit.js'\n\nimport {\n assertNotVariantVersion,\n disabledForVariantVersion,\n type VariantVersionDisabledReason,\n} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {operationsApiClient} from '../utils/operationsApiClient'\nimport {type OperationImpl, type PublishOptions} from './types'\n\nfunction strengthenOnPublish<T>(obj: T): T {\n if (isReference(obj)) {\n if (obj._strengthenOnPublish) {\n return omit(\n obj,\n ['_strengthenOnPublish'].concat(obj._strengthenOnPublish.weak ? [] : ['_weak']),\n ) as T\n }\n return obj\n }\n if (typeof obj !== 'object' || !obj) return obj\n if (Array.isArray(obj)) return obj.map(strengthenOnPublish) as T\n return Object.fromEntries(\n Object.entries(obj).map(([key, value]) => [key, strengthenOnPublish(value)] as const),\n ) as T\n}\n\ntype DisabledReason =\n | 'LIVE_EDIT_ENABLED'\n | 'ALREADY_PUBLISHED'\n | 'NO_CHANGES'\n | VariantVersionDisabledReason\n\nexport const publish: OperationImpl<[options?: PublishOptions], DisabledReason> = {\n disabled: ({schema, typeName, snapshots}) => {\n // Legacy transaction publish. Variant-scoped versions are disabled here — use\n // `serverOperations/publish.ts` instead.\n const variantDisabled = disabledForVariantVersion(snapshots?.version)\n if (variantDisabled) {\n return variantDisabled\n }\n if (isLiveEditEnabled(schema, typeName)) {\n return 'LIVE_EDIT_ENABLED'\n }\n if (!snapshots.draft && !snapshots.version) {\n return snapshots.published ? 'ALREADY_PUBLISHED' : 'NO_CHANGES'\n }\n return false\n },\n execute: ({client, idPair, snapshots}) => {\n if (!snapshots.draft && !snapshots.version) {\n throw new Error('cannot execute \"publish\" when draft or version is missing')\n }\n assertNotVariantVersion(snapshots.version, 'publish')\n\n const value = strengthenOnPublish(\n omit(snapshots.draft || snapshots.version, '_updatedAt') as SanityDocument,\n )\n const tx = operationsApiClient(client, idPair).observable.transaction()\n\n if (snapshots.published) {\n // If it exists already, we only want to update it if the revision on the remote server\n // matches what our local state thinks it's at\n tx.patch(idPair.publishedId, {\n // Hack until other mutations support revision locking\n unset: ['_revision_lock_pseudo_field_'],\n ifRevisionID: snapshots.published._rev,\n })\n\n tx.createOrReplace({\n ...value,\n _id: idPair.publishedId,\n })\n } else {\n // If the document has not been published, we want to create it - if it suddenly exists\n // before being created, we don't want to overwrite if, instead we want to yield an error\n tx.create({\n ...value,\n _id: idPair.publishedId,\n })\n }\n\n tx.delete(value._id)\n\n return tx.commit({tag: 'document.publish', visibility: 'async'})\n },\n}\n","import {type DocumentRevision} from '../../../history/createHistoryStore'\nimport {assertNotVariantVersion, disabledForVariantVersion} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {type OperationImpl} from './types'\n\nexport const restore: OperationImpl<[fromRevision: DocumentRevision]> = {\n // Legacy restore. Variant-scoped versions are disabled here — use `serverOperations/restore.ts`\n // instead.\n disabled: ({snapshots}) => disabledForVariantVersion(snapshots?.version),\n execute: (\n {historyStore, schema, idPair, typeName, snapshots},\n fromRevision: DocumentRevision,\n ) => {\n assertNotVariantVersion(snapshots.version, 'restore')\n const targetId = idPair.versionId\n ? idPair.versionId\n : isLiveEditEnabled(schema, typeName)\n ? idPair.publishedId\n : idPair.draftId\n\n return historyStore.restore(idPair.publishedId, targetId, fromRevision)\n },\n}\n","import omit from 'lodash-es/omit.js'\n\nimport {\n assertNotVariantVersion,\n disabledForVariantVersion,\n type VariantVersionDisabledReason,\n} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {operationsApiClient} from '../utils/operationsApiClient'\nimport {type OperationImpl} from './types'\n\ntype DisabledReason = 'LIVE_EDIT_ENABLED' | 'NOT_PUBLISHED' | VariantVersionDisabledReason\n\nexport const unpublish: OperationImpl<[], DisabledReason> = {\n disabled: ({schema, snapshots, typeName}) => {\n // Legacy transaction unpublish. Variant-scoped versions are disabled here — use\n // `serverOperations/unpublish.ts` instead.\n const variantDisabled = disabledForVariantVersion(snapshots?.version)\n if (variantDisabled) {\n return variantDisabled\n }\n if (isLiveEditEnabled(schema, typeName)) {\n return 'LIVE_EDIT_ENABLED'\n }\n return snapshots.published ? false : 'NOT_PUBLISHED'\n },\n execute: ({client, idPair, snapshots}) => {\n assertNotVariantVersion(snapshots.version, 'unpublish')\n\n let tx = operationsApiClient(client, idPair).observable.transaction().delete(idPair.publishedId)\n\n if (snapshots.published) {\n tx = tx.createIfNotExists({\n ...omit(snapshots.published, '_updatedAt'),\n _id: idPair.draftId,\n _type: snapshots.published._type,\n })\n }\n\n return tx.commit({\n tag: 'document.unpublish',\n visibility: 'async',\n // this disables referential integrity for cross-dataset references. we\n // have this set because we warn against unpublishes in the `ConfirmDeleteDialog`\n // UI. This operation is run when \"unpublish anyway\" is clicked\n skipCrossDatasetReferenceValidation: true,\n })\n },\n}\n","import {isPublishedId} from '@sanity/client/csm'\n\nimport {type OperationImpl} from '../operations/types'\nimport {actionsApiClient} from '../utils/actionsApiClient'\n\nexport const del: OperationImpl<[versions?: string[]], 'NOTHING_TO_DELETE'> = {\n disabled: ({snapshots}) =>\n snapshots.draft || snapshots.published || snapshots.version ? false : 'NOTHING_TO_DELETE',\n execute: ({client, idPair, snapshots}, versions = []) => {\n //the delete action requires a published doc -- discard versions if not present\n if (!snapshots.published) {\n return actionsApiClient(client, idPair).observable.action(\n versions.map((versionId) => ({\n actionType: 'sanity.action.document.version.discard',\n versionId,\n })),\n {\n skipCrossDatasetReferenceValidation: true,\n },\n )\n }\n\n return actionsApiClient(client, idPair).observable.action(\n {\n actionType: 'sanity.action.document.delete',\n includeDrafts: versions\n ? // if versions are provided, remove the published id from the list, all versions need to be included in order for the delete to work.\n versions.filter((v) => !isPublishedId(v))\n : snapshots.draft\n ? [idPair.draftId]\n : [],\n publishedId: idPair.publishedId,\n },\n {\n tag: 'document.delete',\n // this disables referential integrity for cross-dataset references. we\n // have this set because we warn against deletes in the `ConfirmDeleteDialog`\n // UI. This operation is run when \"delete anyway\" is clicked\n skipCrossDatasetReferenceValidation: true,\n },\n )\n },\n}\n","import {getVariantVersionInfo} from '../../../../variants/documents/getVariantVersionInfo'\nimport {type OperationImpl} from '../operations/types'\nimport {actionsApiClient} from '../utils/actionsApiClient'\n\ntype DisabledReason = 'NO_CHANGES'\n\nexport const discardChanges: OperationImpl<[], DisabledReason> = {\n disabled: ({snapshots}) => {\n if (!snapshots.draft && !snapshots.version) {\n return 'NO_CHANGES'\n }\n // The variant-of-published document has no draft-ness to discard; removing the published\n // variant is unpublish's job.\n if (getVariantVersionInfo(snapshots.version)?.bundleId === 'published') {\n return 'NO_CHANGES'\n }\n return false\n },\n execute: ({client, idPair, snapshots}) => {\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion?.bundleId === 'published') {\n throw new Error('Cannot discard changes of a published variant: unpublish it instead')\n }\n\n return actionsApiClient(client, idPair).observable.action(\n {\n actionType: 'sanity.action.document.version.discard',\n versionId: idPair.versionId || idPair.draftId,\n },\n {tag: 'document.discard-changes'},\n )\n },\n}\n","import {type OperationImpl} from '../operations/types'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\n\nexport const patch: OperationImpl<[patches: any[], initialDocument?: Record<string, any>]> = {\n disabled: (): false => false,\n execute: (\n {schema, snapshots, idPair, draft, published, version, typeName},\n patches = [],\n initialDocument,\n ): void => {\n if (version) {\n // No drafting, so patch and commit the version document.\n const patchMutation = version.patch(patches)\n // Note: if the document doesn't exist on the server yet, we need to create it first. We only want to do this if we can't see it locally\n // if it's been deleted on the server we want that to become a mutation error when submitting.\n const ensureVersion = snapshots.version\n ? version.patch([\n {\n unset: ['_empty_action_guard_pseudo_field_'],\n },\n ])\n : [\n version.create({\n ...initialDocument,\n _id: idPair.draftId,\n _type: typeName,\n }),\n ]\n // No drafting, so patch and commit the published document\n version.mutate([...ensureVersion, ...patchMutation])\n\n return\n }\n\n if (isLiveEditEnabled(schema, typeName)) {\n // No drafting, so patch and commit the published document\n const patchMutation = published.patch(patches)\n // Note: if the document doesn't exist on the server yet, we need to create it first. We only want to do this if we can't see it locally\n // if it's been deleted on the server we want that to become a mutation error when submitting.\n const mutations = snapshots.published\n ? patchMutation\n : [\n published.createIfNotExists({\n _type: typeName,\n ...initialDocument,\n }),\n ...patchMutation,\n ]\n // No drafting, so patch and commit the published document\n published.mutate(mutations)\n\n return\n }\n\n const patchMutation = draft.patch(patches)\n if (snapshots.draft) {\n draft.mutate([\n ...draft.patch([{unset: ['_empty_action_guard_pseudo_field_']}]),\n ...patchMutation,\n ])\n return\n }\n\n // At this point we don't have a draft, so we need to create it.\n // Only use the createMutation if the draft doesn't exist.\n // Creation will happen in a different transaction than the patch, to get the correct initial value for it.\n\n const createMutation = snapshots.published\n ? // If there's no draft, the user's edits will be based on the published document in the form in front of them\n // so before patching it we need to make sure it's created based on the current published version first.\n draft.createIfNotExists({\n ...initialDocument,\n ...snapshots.published,\n _id: idPair.draftId,\n _type: typeName,\n })\n : // If the published doesn't exist we need to trigger a `create` action, because we are internally\n // transforming the createIfNotExists action to a patch, which requires the published document to exist.\n // see checkoutPair.ts toActions function for more details.\n draft.create({\n ...initialDocument,\n _id: idPair.draftId,\n _type: typeName,\n })\n\n draft.mutate([createMutation])\n // Commit so we create the draft in a different transaction than the patch, and we get the correct initial value for it.\n draft.commit()\n // We do it in two steps to first create the draft with the copied version and then reflect the user edit to preserve the history.\n draft.mutate(patchMutation)\n },\n}\n","import {getVariantVersionInfo} from '../../../../variants/documents/getVariantVersionInfo'\nimport {type OperationImpl, type PublishOptions} from '../operations/types'\nimport {actionsApiClient} from '../utils/actionsApiClient'\nimport {assertNotVariantVersion} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {variantsApiClient} from '../utils/variantsApiClient'\n\ntype DisabledReason = 'LIVE_EDIT_ENABLED' | 'ALREADY_PUBLISHED' | 'NO_CHANGES' | 'NOT_PUBLISHABLE'\n\nexport const publish: OperationImpl<[options?: PublishOptions], DisabledReason> = {\n disabled: ({schema, typeName, snapshots}) => {\n if (isLiveEditEnabled(schema, typeName)) {\n return 'LIVE_EDIT_ENABLED'\n }\n\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion) {\n // The checked-out version IS the variant-of-published document: nothing to publish.\n if (variantVersion.bundleId === 'published') {\n return 'ALREADY_PUBLISHED'\n }\n // Release-scoped variant documents are published as part of their release, mirroring how\n // plain release versions are not publishable by this action.\n if (snapshots.version?._system?.release?._ref) {\n return 'NOT_PUBLISHABLE'\n }\n return false\n }\n\n if (!snapshots.draft && !snapshots.version) {\n return snapshots.published ? 'ALREADY_PUBLISHED' : 'NO_CHANGES'\n }\n return false\n },\n execute: ({client, idPair, snapshots}, options) => {\n // The editor must be able to see the draft they are choosing to publish.\n if (!snapshots.draft && !snapshots.version) {\n throw new Error('cannot execute \"publish\" when draft or version is missing')\n }\n if (idPair.versionId && !snapshots.version) {\n throw new Error('cannot execute \"publish\" when version is missing but versionId is provided')\n }\n\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion) {\n if (variantVersion.bundleId === 'published') {\n throw new Error(\n 'cannot execute \"publish\" on a variant-of-published document: it is already published',\n )\n }\n\n // Publishes the variant document into the variant-of-published document. The base\n // published document is never touched.\n //\n // `publishedRevisionId` → `ifPublishedVariantRevisionId` locks on the\n // variant-of-published sibling revision (passed from PublishAction via\n // `publishedSibling._rev` — that sibling is not in any pair snapshot slot).\n // `ifSourceRevisionId` is still omitted: the deployed action rejects it\n // (`json: unknown field`).\n // TODO(SAPP): send `ifSourceRevisionId: snapshots.version?._rev` once the action supports it.\n return variantsApiClient(client).observable.action(\n {\n actionType: 'sanity.action.document.variant.publish',\n publishedId: idPair.publishedId,\n variantId: variantVersion.variantId,\n bundleId: variantVersion.bundleId,\n ifPublishedVariantRevisionId: options?.publishedRevisionId,\n },\n {tag: 'document.publish'},\n )\n }\n\n assertNotVariantVersion(snapshots.version, 'publish')\n\n return actionsApiClient(client, idPair).observable.action(\n {\n actionType: 'sanity.action.document.publish',\n draftId: (snapshots.version?._id || snapshots.draft?._id)!,\n publishedId: idPair.publishedId,\n // Optimistic locking using `ifPublishedRevisionId` ensures that concurrent publish action\n // invocations do not override each other. Prefer an explicit `publishedRevisionId` when\n // provided; otherwise fall back to the published snapshot (the normal draft path).\n //\n // Note: for custom publish actions, `snapshots.draft._rev` may be stale, which means the\n // `ifDraftRevisionId` optimistic lock cannot currently be used.\n ifPublishedRevisionId: options?.publishedRevisionId ?? snapshots.published?._rev,\n },\n {\n tag: 'document.publish',\n },\n )\n },\n}\n","import {type DocumentRevision} from '../../../history/createHistoryStore'\nimport {type OperationImpl} from '../operations/types'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\n\nexport const restore: OperationImpl<[fromRevision: DocumentRevision]> = {\n disabled: (): false => false,\n execute: (\n {snapshots, historyStore, schema, idPair, typeName},\n fromRevision: DocumentRevision,\n ) => {\n const targetId = idPair.versionId\n ? idPair.versionId\n : isLiveEditEnabled(schema, typeName)\n ? idPair.publishedId\n : idPair.draftId\n\n return historyStore.restore(idPair.publishedId, targetId, fromRevision, {\n fromDeleted: !snapshots.draft && !snapshots.published,\n useServerDocumentActions: true,\n })\n },\n}\n","import {type SanityDocument} from '@sanity/client'\nimport {type SanityDocumentLike} from '@sanity/types'\n\n/**\n * checks if the document has been set for unpublishing\n * @internal\n *\n * @param document - sanity document\n * @returns boolean if the system delete is set\n */\nexport function isGoingToUnpublish(document: SanityDocument | SanityDocumentLike): boolean {\n return Boolean(document._system?.delete === true)\n}\n","import {isGoingToUnpublish} from '../../../../releases/util/isGoingToUnpublish'\nimport {getVariantVersionInfo} from '../../../../variants/documents/getVariantVersionInfo'\nimport {VARIANTS_STUDIO_CLIENT_OPTIONS} from '../../../../variants/store/constants'\nimport {type OperationImpl} from '../operations/types'\nimport {actionsApiClient} from '../utils/actionsApiClient'\nimport {assertNotVariantVersion} from '../utils/assertNotVariantVersion'\nimport {isLiveEditEnabled} from '../utils/isLiveEditEnabled'\nimport {variantsApiClient} from '../utils/variantsApiClient'\n\ntype DisabledReason = 'LIVE_EDIT_ENABLED' | 'NOT_PUBLISHED' | 'ALREADY_UNPUBLISHED'\n\nexport const unpublish: OperationImpl<[], DisabledReason> = {\n disabled: ({schema, snapshots, typeName, idPair}) => {\n if (isLiveEditEnabled(schema, typeName) && !idPair.versionId) {\n return 'LIVE_EDIT_ENABLED'\n }\n\n // A release version already carrying the unpublish marker would be a no-op: the release\n // publish will remove the published document either way. Reverting it is a separate\n // operation (`revertUnpublishVersion`), not a repeated unpublish.\n if (idPair.versionId && snapshots.version && isGoingToUnpublish(snapshots.version)) {\n return 'ALREADY_UNPUBLISHED'\n }\n\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion) {\n // Unpublishable variant versions:\n // - the variant-of-published document itself (no bundleId), which is hard-unpublished\n // - a release-scoped variant, which is soft-unpublished as part of its release\n // A drafts-scoped variant has nothing published in its slot to unpublish.\n return variantVersion.bundleId !== 'drafts' ? false : 'NOT_PUBLISHED'\n }\n\n return snapshots.published ? false : 'NOT_PUBLISHED'\n },\n execute: ({client, idPair, snapshots}) => {\n const variantVersion = getVariantVersionInfo(snapshots.version)\n if (variantVersion) {\n if (variantVersion.bundleId === 'drafts') {\n throw new Error('Cannot unpublish a draft variant')\n }\n // `bundleId` is the version snapshot's own bundle:\n // - `undefined` (variant-of-published): hard unpublish — the backend deletes the published\n // variant and creates the variant draft from its content (mirror of base unpublish)\n // - a release id: soft unpublish — the backend marks the release-scoped variant with\n // `_system.delete: true`, completed when the release is published\n // The base published and draft documents are never touched either way.\n return variantsApiClient(client).observable.action(\n {\n actionType: 'sanity.action.document.variant.unpublish',\n publishedId: idPair.publishedId,\n variantId: variantVersion.variantId,\n bundleId: snapshots.version?._system?.bundleId,\n },\n {\n tag: 'document.unpublish',\n skipCrossDatasetReferenceValidation: true,\n },\n )\n }\n\n assertNotVariantVersion(snapshots.version, 'unpublish')\n\n if (idPair.versionId) {\n // Unpublishing inside a release is a soft unpublish: the backend marks the release version\n // with `_system.delete: true` and removes the published document when the release is\n // published. The base draft is deliberately absent from the payload — unlike the base\n // unpublish below, nothing is written back into `drafts.<id>`.\n return actionsApiClient(client, idPair).observable.action(\n {\n actionType: 'sanity.action.document.version.unpublish',\n versionId: idPair.versionId,\n publishedId: idPair.publishedId,\n },\n {\n tag: 'document.unpublish',\n skipCrossDatasetReferenceValidation: true,\n },\n )\n }\n\n return actionsApiClient(client, idPair).observable.action(\n {\n // This operation is run when \"unpublish anyway\" is clicked\n actionType: 'sanity.action.document.unpublish',\n draftId: idPair.draftId,\n publishedId: idPair.publishedId,\n },\n {\n tag: 'document.unpublish',\n // this disables referential integrity for cross-dataset references. we\n // have this set because we warn against unpublishes in the `ConfirmDeleteDialog`\n // UI.\n skipCrossDatasetReferenceValidation: true,\n },\n )\n },\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type Schema} from '@sanity/types'\nimport {asyncScheduler, defer, EMPTY, merge, type Observable, of, Subject, timer} from 'rxjs'\nimport {\n catchError,\n concatMap,\n filter,\n groupBy,\n last,\n map,\n mergeMap,\n mergeMapTo,\n share,\n switchMap,\n take,\n tap,\n throttleTime,\n} from 'rxjs/operators'\n\nimport {type HistoryStore} from '../../history/createHistoryStore'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {createMemoKey, getClientCredentialSegments} from '../utils/memoKey'\nimport {consistencyStatus} from './consistencyStatus'\nimport {getOperationStoreKey} from './getOperationStoreKey'\nimport {operationArgs} from './operationArgs'\nimport {commit} from './operations/commit'\nimport {del} from './operations/delete'\nimport {discardChanges} from './operations/discardChanges'\nimport {duplicate} from './operations/duplicate'\nimport {patch} from './operations/patch'\nimport {publish} from './operations/publish'\nimport {restore} from './operations/restore'\nimport {type OperationArgs, type OperationsAPI} from './operations/types'\nimport {unpublish} from './operations/unpublish'\nimport {del as serverDel} from './serverOperations/delete'\nimport {discardChanges as serverDiscardChanges} from './serverOperations/discardChanges'\nimport {patch as serverPatch} from './serverOperations/patch'\nimport {publish as serverPublish} from './serverOperations/publish'\nimport {restore as serverRestore} from './serverOperations/restore'\nimport {unpublish as serverUnpublish} from './serverOperations/unpublish'\n\ninterface ExecuteArgs {\n operationName: keyof OperationsAPI\n idPair: IdPair\n typeName: string\n storeKey?: string\n extraArgs: any[]\n}\n\nfunction maybeObservable(v: void | Observable<any>) {\n return typeof v === 'undefined' ? of(null) : v\n}\n\nconst operationImpls = {\n del: del,\n delete: del,\n publish,\n patch,\n commit,\n discardChanges,\n unpublish,\n duplicate,\n restore,\n} as const\n\n//as we add server operations one by one, we can add them here\n// Note: Any changes must also be made to `createOperationsAPI`, which is defined in `packages/sanity/src/core/store/document/document-pair/operations/helpers.ts`.\nconst serverOperationImpls = {\n ...operationImpls,\n del: serverDel,\n delete: serverDel,\n discardChanges: serverDiscardChanges,\n patch: serverPatch,\n publish: serverPublish,\n unpublish: serverUnpublish,\n restore: serverRestore,\n}\n\nconst execute = (\n operationName: keyof typeof operationImpls,\n operationArguments: OperationArgs,\n extraArgs: any[],\n): Observable<any> => {\n const operation = serverOperationImpls[operationName]\n return defer(() =>\n merge(of(null), maybeObservable(operation.execute(operationArguments, ...extraArgs))),\n ).pipe(last())\n}\n\nconst operationCalls$ = new Subject<ExecuteArgs>()\n\n/** @internal */\nexport function emitOperation(\n operationName: keyof OperationsAPI,\n idPair: IdPair,\n typeName: string,\n extraArgs: any[],\n storeKey?: string,\n): void {\n operationCalls$.next({operationName, idPair, typeName, storeKey, extraArgs})\n}\n\n// These are the operations that cannot be performed while the document is in an inconsistent state\nconst REQUIRES_CONSISTENCY = ['publish', 'unpublish', 'discardChanges', 'delete']\n\n/**\n * @hidden\n * @beta */\nexport interface OperationError {\n type: 'error'\n /** @internal */\n op: keyof OperationsAPI\n id: string\n error: Error\n idPair: IdPair\n}\n\n/**\n * @hidden\n * @beta */\nexport interface OperationSuccess {\n type: 'success'\n /** @internal */\n op: keyof OperationsAPI\n id: string\n idPair: IdPair\n}\n\ninterface IntermediarySuccess {\n type: 'success'\n args: ExecuteArgs\n}\n\ninterface IntermediaryError {\n type: 'error'\n args: ExecuteArgs\n error: any\n}\n\n/** @internal */\nexport const operationEvents = memoize(\n (ctx: {\n client: SanityClient\n historyStore: HistoryStore\n schema: Schema\n /**\n * @deprecated Does nothing. Preserved to avoid breaking changes.\n * Will be removed in the next major version.\n */\n serverActionsEnabled?: Observable<boolean>\n extraOptions?: DocumentStoreExtraOptions\n }) => {\n const storeKey = getOperationStoreKey(ctx.client)\n const result$: Observable<IntermediarySuccess | IntermediaryError> = operationCalls$.pipe(\n filter((op) => op.storeKey === storeKey || !op.storeKey),\n groupBy((op) => op.idPair.publishedId),\n mergeMap((groups$) =>\n groups$.pipe(\n // although it might look like a bug, dropping pending async operations here is actually a feature\n // E.g. if the user types `publish` which is async and then starts patching (sync) then the publish\n // should be cancelled\n switchMap((args) =>\n operationArgs(ctx, args.idPair, args.typeName).pipe(\n take(1),\n switchMap((operationArguments) => {\n const requiresConsistency = REQUIRES_CONSISTENCY.includes(args.operationName)\n if (requiresConsistency) {\n operationArguments.published.commit()\n operationArguments.draft.commit()\n operationArguments.version?.commit()\n }\n const isConsistent$ = consistencyStatus(\n ctx.client,\n args.idPair,\n args.typeName,\n ctx.extraOptions,\n ).pipe(filter(Boolean))\n const ready$ = requiresConsistency ? isConsistent$.pipe(take(1)) : of(true)\n return ready$.pipe(\n switchMap(() => execute(args.operationName, operationArguments, args.extraArgs)),\n )\n }),\n map((): IntermediarySuccess => ({type: 'success', args})),\n catchError((err): Observable<IntermediaryError> =>\n of({type: 'error', args, error: err}),\n ),\n ),\n ),\n ),\n ),\n share(),\n )\n\n // this enables autocommit after patch operations\n const AUTOCOMMIT_INTERVAL = 1000\n const autoCommit$ = result$.pipe(\n filter((result) => result.type === 'success' && result.args.operationName === 'patch'),\n throttleTime(AUTOCOMMIT_INTERVAL, asyncScheduler, {leading: true, trailing: true}),\n concatMap((result) =>\n (window as any).SLOW ? timer(10000).pipe(map(() => result)) : of(result),\n ),\n tap((result) => {\n emitOperation('commit', result.args.idPair, result.args.typeName, [], result.args.storeKey)\n }),\n )\n\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n return merge(result$, autoCommit$.pipe(mergeMapTo(EMPTY)))\n },\n (ctx) =>\n // Per credential (token+dataset+projectId): this captures `ctx.client` and\n // drives commits/mutations through it, so a cross-tab re-login (new token)\n // must get a fresh entry rather than replaying the stale-token client. See\n // getClientCredentialSegments.\n createMemoKey(getClientCredentialSegments(ctx.client)),\n)\n","import {type IdPair} from '../../types'\nimport {getOperationStoreKey} from '../getOperationStoreKey'\nimport {emitOperation} from '../operationEvents'\nimport {del as serverDel} from '../serverOperations/delete'\nimport {discardChanges as serverDiscardChanges} from '../serverOperations/discardChanges'\nimport {patch as serverPatch} from '../serverOperations/patch'\nimport {publish as serverPublish} from '../serverOperations/publish'\nimport {restore as serverRestore} from '../serverOperations/restore'\nimport {unpublish as serverUnpublish} from '../serverOperations/unpublish'\nimport {commit} from './commit'\nimport {duplicate} from './duplicate'\nimport {type Operation, type OperationArgs, type OperationImpl, type OperationsAPI} from './types'\n\nfunction createOperationGuard(opName: string): Operation<any[], 'NOT_READY'> {\n return {\n disabled: 'NOT_READY',\n execute: () => {\n throw new Error(`Called ${opName} before it was ready.`)\n },\n }\n}\n\n// This creates a version of the operations api that will throw if called.\n// Most operations depend on having the \"current document state\" available locally and if an action gets called\n// before we have the state available, we throw an error to signal \"premature\" invocation before ready\nexport const GUARDED: OperationsAPI = {\n commit: createOperationGuard('commit'),\n delete: createOperationGuard('delete'),\n del: createOperationGuard('del'),\n publish: createOperationGuard('publish'),\n patch: createOperationGuard('patch'),\n discardChanges: createOperationGuard('discardChanges'),\n unpublish: createOperationGuard('unpublish'),\n duplicate: createOperationGuard('duplicate'),\n restore: createOperationGuard('restore'),\n}\n\nfunction createTargetNotFoundOperation(opName: string): Operation<any[], 'TARGET_NOT_FOUND'> {\n return {\n disabled: 'TARGET_NOT_FOUND',\n execute: () => {\n throw new Error(\n `Cannot execute \"${opName}\": the selected target (release or variant) does not contain this document.`,\n )\n },\n }\n}\n\n// The operations api emitted when the declared target (release or variant) has no document.\n// Every operation is disabled and throws if executed anyway: falling back to the base\n// draft/published pair in this state is exactly the failure mode the guard exists to prevent.\nexport const TARGET_NOT_FOUND_OPERATIONS: OperationsAPI = {\n commit: createTargetNotFoundOperation('commit'),\n delete: createTargetNotFoundOperation('delete'),\n del: createTargetNotFoundOperation('del'),\n publish: createTargetNotFoundOperation('publish'),\n patch: createTargetNotFoundOperation('patch'),\n discardChanges: createTargetNotFoundOperation('discardChanges'),\n unpublish: createTargetNotFoundOperation('unpublish'),\n duplicate: createTargetNotFoundOperation('duplicate'),\n restore: createTargetNotFoundOperation('restore'),\n}\nconst OPERATION_NAMES = Object.keys(GUARDED) as (keyof OperationsAPI)[]\n\n/**\n * `execute` only emits the operation name with the id pair, type name and store key the api\n * was created for; the arguments are read from the live `operationArgs` stream at execution\n * time. `disabled` is therefore the only field a consumer can observe changing.\n */\nexport function hasSameDisabledState(a: OperationsAPI, b: OperationsAPI): boolean {\n return OPERATION_NAMES.every((name) => a[name].disabled === b[name].disabled)\n}\n\nconst createEmitter =\n (operationName: keyof OperationsAPI, idPair: IdPair, typeName: string, storeKey: string) =>\n (...executeArgs: any[]) =>\n emitOperation(operationName, idPair, typeName, executeArgs, storeKey)\n\nfunction wrap<ExtraArgs extends any[], DisabledReason extends string>(\n opName: keyof OperationsAPI,\n op: OperationImpl<ExtraArgs, DisabledReason>,\n operationArgs: OperationArgs,\n): Operation<ExtraArgs, DisabledReason> {\n const disabled = op.disabled(operationArgs)\n const storeKey = getOperationStoreKey(operationArgs.client)\n return {\n disabled,\n execute: createEmitter(opName, operationArgs.idPair, operationArgs.typeName, storeKey),\n }\n}\n\nexport function createOperationsAPI(args: OperationArgs): OperationsAPI {\n const operations: OperationsAPI = {\n commit: wrap('commit', commit, args),\n duplicate: wrap('duplicate', duplicate, args),\n delete: wrap('delete', serverDel, args),\n del: wrap('delete', serverDel, args),\n discardChanges: wrap('discardChanges', serverDiscardChanges, args),\n patch: wrap('patch', serverPatch, args),\n publish: wrap('publish', serverPublish, args),\n unpublish: wrap('unpublish', serverUnpublish, args),\n restore: wrap('restore', serverRestore, args),\n }\n\n // Self-derived target guard: a version was requested for an existing document, but the version\n // document doesn't exist. Mutating in this state would silently manifest the version out of\n // thin air (`patch` creates the version document) or operate on the base pair (`publish` would\n // publish the draft), so the mutating operations are disabled regardless of what the caller\n // declared. Deliberately excluded:\n // - New documents (no draft, published, or version snapshots): typing must still create the\n // release version locally via its deterministic id (create-on-first-edit).\n // - `restore` (history restore into a release) legitimately creates missing versions.\n // - `delete` / `duplicate` operate on the whole document group.\n const targetVersionMissing = Boolean(\n args.idPair.versionId &&\n !args.snapshots.version &&\n (args.snapshots.draft || args.snapshots.published),\n )\n\n if (!targetVersionMissing) {\n return operations\n }\n\n // A declared creatable variant target: the variant document doesn't exist yet, but its id is\n // known ahead of time (the server-advertised `_system.draft` weak ref on the variant-of-published\n // sibling), so typing must create it seeded from the published variant — exactly like the base\n // pair creates the draft from published. Only `patch` and `commit` are exempted: the document\n // still doesn't exist, so publish/unpublish/discardChanges stay `TARGET_NOT_FOUND` until it does.\n const allowVersionCreate = args.target?.kind === 'variant' && args.target.allowCreate === true\n\n return {\n ...operations,\n commit: allowVersionCreate ? operations.commit : createTargetNotFoundOperation('commit'),\n patch: allowVersionCreate ? operations.patch : createTargetNotFoundOperation('patch'),\n publish: createTargetNotFoundOperation('publish'),\n unpublish: createTargetNotFoundOperation('unpublish'),\n discardChanges: createTargetNotFoundOperation('discardChanges'),\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type Schema} from '@sanity/types'\nimport {concat, EMPTY, merge, type Observable, of} from 'rxjs'\nimport {distinctUntilChanged, map, mergeMap, shareReplay} from 'rxjs/operators'\n\nimport {type HistoryStore} from '../../history/createHistoryStore'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type DocumentPairTarget, type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {memoizeKeyGen} from './memoizeKeyGen'\nimport {operationArgs} from './operationArgs'\nimport {operationEvents} from './operationEvents'\nimport {createOperationsAPI, GUARDED, hasSameDisabledState} from './operations/helpers'\nimport {type OperationsAPI} from './operations/types'\n\nexport const editOperations = memoize(\n (\n ctx: {\n client: SanityClient\n historyStore: HistoryStore\n schema: Schema\n pairListenerOptions?: DocumentStoreExtraOptions\n },\n idPair: IdPair,\n typeName: string,\n // The declared pair target. Threaded into `OperationArgs` (not into the shared, memoized\n // `operationArgs` stream) so the self-derived missing-version guard can honor a declared\n // creatable variant target (`allowCreate`).\n target?: DocumentPairTarget,\n ): Observable<OperationsAPI> => {\n const operationEvents$ = operationEvents(ctx)\n\n const operationArgs$ = operationArgs(ctx, idPair, typeName)\n const operations$ = operationArgs$.pipe(\n map((args) => createOperationsAPI({...args, target})),\n distinctUntilChanged(hasSameDisabledState),\n )\n\n // To makes sure we connect the stream that actually performs the operations\n return concat(\n of(GUARDED),\n merge(operationEvents$.pipe(mergeMap(() => EMPTY)), operations$),\n ).pipe(shareReplay({refCount: true, bufferSize: 1}))\n },\n (ctx, idPair, typeName, target) =>\n // `allowCreate` changes the emitted operations for the same pair, so it must partake in the\n // memo key or a creatable and a non-creatable caller would collide on one cached stream.\n `${memoizeKeyGen(ctx.client, idPair, typeName)}-${\n target?.kind === 'variant' && target.allowCreate ? 'allow-create' : ''\n }`,\n)\n","// api extractor take issues with 'as const' for literals\n// oxlint-disable-next-line prefer-as-const\nexport const RELEASE_DOCUMENT_TYPE: 'system.release' = 'system.release'\nexport const RELEASE_DOCUMENTS_PATH = '_.releases'\n","import {type ReleaseId} from '../../perspective/types'\nimport {RELEASE_DOCUMENTS_PATH} from '../store/constants'\n\nconst PATH_ID_PREFIX = `${RELEASE_DOCUMENTS_PATH}.`\n\n/**\n * Whether the given id addresses a release document (`_.releases.<releaseId>`) rather than\n * being a release id or a system bundle name.\n *\n * @internal\n */\nexport function isReleaseDocumentId(id: string): boolean {\n return id.startsWith(PATH_ID_PREFIX)\n}\n\n/**\n * @internal\n * @param releaseDocumentId - the document id of the release\n */\nexport function getReleaseIdFromReleaseDocumentId(releaseDocumentId: string): ReleaseId {\n if (!releaseDocumentId.startsWith(PATH_ID_PREFIX)) {\n throw new Error(\n `Release document ID was ${releaseDocumentId} but should start with ${RELEASE_DOCUMENTS_PATH}`,\n )\n }\n const releaseId = releaseDocumentId.slice(PATH_ID_PREFIX.length)\n return releaseId\n}\n","import {type MonoTypeOperatorFunction} from 'rxjs'\nimport {tap} from 'rxjs/operators'\n\n/**\n * RxJS operator that measures the time from subscription to the first emission.\n * Calls `onMeasured` once with the elapsed duration in milliseconds and the emitted value.\n * Uses `tap()` internally so data flow is unchanged.\n *\n * Re-subscriptions (e.g. navigating between documents) naturally produce fresh measurements.\n *\n * @param onMeasured - Callback receiving the duration in ms and the first emitted value\n * @returns An RxJS operator\n * @internal\n */\nexport function measureFirstEmission<T>(\n onMeasured: (durationMs: number, value: T) => void,\n): MonoTypeOperatorFunction<T> {\n return (source) => {\n let measured = false\n let startTime: number\n\n return source.pipe(\n tap({\n subscribe: () => {\n measured = false\n startTime = performance.now()\n },\n next: (value) => {\n if (!measured) {\n measured = true\n onMeasured(performance.now() - startTime, value)\n }\n },\n }),\n )\n }\n}\n\n/**\n * RxJS operator that measures the time from subscription to the first emission\n * where the given predicate returns `true`.\n * Calls `onMeasured` once with the elapsed duration in milliseconds and the matching value.\n * Uses `tap()` internally so data flow is unchanged.\n *\n * @param predicate - Function that determines if the emitted value is a match\n * @param onMeasured - Callback receiving the duration in ms and the first matching value\n * @returns An RxJS operator\n * @internal\n */\nexport function measureFirstMatch<T>(\n predicate: (value: T) => boolean,\n onMeasured: (durationMs: number, value: T) => void,\n): MonoTypeOperatorFunction<T> {\n return (source) => {\n let measured = false\n let startTime: number\n\n return source.pipe(\n tap({\n subscribe: () => {\n measured = false\n startTime = performance.now()\n },\n next: (value) => {\n if (!measured && predicate(value)) {\n measured = true\n onMeasured(performance.now() - startTime, value)\n }\n },\n }),\n )\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type SanityDocument, type Schema} from '@sanity/types'\nimport {combineLatest, type Observable, of, ReplaySubject, timer} from 'rxjs'\nimport {map, share, startWith, switchMap} from 'rxjs/operators'\n\nimport {getReleaseIdFromReleaseDocumentId} from '../../../releases/util/getReleaseIdFromReleaseDocumentId'\nimport {getVersionFromId} from '../../../util/draftUtils'\nimport {measureFirstEmission} from '../../../util/measureFirstEmission'\nimport {createSWR} from '../../../util/rxSwr'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair, type PendingMutationsEvent} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {memoizeKeyGen} from './memoizeKeyGen'\nimport {snapshotPair} from './snapshotPair'\nimport {isLiveEditEnabled} from './utils/isLiveEditEnabled'\n\ninterface TransactionSyncLockState {\n enabled: boolean\n}\n\nconst swr = createSWR<\n [SanityDocument, SanityDocument, TransactionSyncLockState, SanityDocument | null]\n>({maxSize: 50})\n\n/**\n * @hidden\n * @beta */\nexport interface EditStateFor {\n id: string\n type: string\n transactionSyncLock: TransactionSyncLockState | null\n draft: SanityDocument | null\n published: SanityDocument | null\n version: SanityDocument | null\n /**\n * Whether live edit is enabled. This may be true for various reasons:\n *\n * - The schema type has live edit enabled.\n * - A version of the document is checked out.\n */\n liveEdit: boolean\n /**\n * Whether the schema type has live edit enabled.\n */\n liveEditSchemaType: boolean\n ready: boolean\n /**\n * When editing a version, the short name of the release the document belongs to (or an agent /\n * anonymous bundle name), matched by consumers against active release names. Never an opaque\n * variant scope hash: documents carrying full `_system` metadata are classified from\n * `_system.release` (normalized from the `_.releases.<name>` reference), so drafts- and\n * published-scoped variants report `undefined` while release-scoped versions — variant or not —\n * report their release. Until the first snapshot arrives, the bundle segment is reported as-is.\n */\n release: string | undefined\n /**\n * When editing a version, the bundle segment of the version document id\n * (`versions.<scopeId>.<groupId>`): a release id, an agent/anonymous bundle name, or an opaque\n * variant scope hash. `undefined` when editing the base draft/published pair.\n */\n scopeId: string | undefined\n}\nconst LOCKED: TransactionSyncLockState = {enabled: true}\nconst NOT_LOCKED: TransactionSyncLockState = {enabled: false}\n\n/**\n * Classifies `EditStateFor.release` from a version snapshot.\n *\n * Documents carrying the full `_system` metadata (`_system.group` present) are classified from\n * `_system.release`, which is authoritative: a reference to the release document\n * (`_.releases.<name>`), normalized here to the short release name every consumer matches\n * against. Version documents without a release reference (e.g. drafts- or published-scoped\n * variants) report `undefined`.\n *\n * Unmigrated documents (no `_system.group`) can only be plain release versions, so the bundle\n * segment of their id (`scopeId`) is the release name.\n */\nfunction classifyRelease(\n versionSnapshot: SanityDocument | null,\n scopeId: string | undefined,\n): string | undefined {\n if (!versionSnapshot || !versionSnapshot._system?.group) {\n return scopeId\n }\n const releaseRef = versionSnapshot._system.release?._ref\n if (!releaseRef) {\n return undefined\n }\n return getReleaseIdFromReleaseDocumentId(releaseRef)\n}\n\n/**\n * The edit state before any snapshot has arrived. `editState` emits it first, and `useEditState`\n * renders it until the pipeline emits.\n *\n * @internal\n */\nexport function getInitialEditState(\n schema: Schema,\n idPair: IdPair,\n typeName: string,\n): EditStateFor {\n const liveEditSchemaType = isLiveEditEnabled(schema, typeName)\n const scopeId = idPair.versionId ? getVersionFromId(idPair.versionId) : undefined\n\n return {\n id: idPair.publishedId,\n type: typeName,\n draft: null,\n published: null,\n version: null,\n liveEdit: typeof idPair.versionId !== 'undefined' || liveEditSchemaType,\n liveEditSchemaType,\n ready: false,\n transactionSyncLock: null,\n release: scopeId,\n scopeId,\n }\n}\n\n// How long to keep the pipeline alive after the last subscriber unsubscribes.\n// Subscriber churn (e.g. a React commit that unsubscribes every consumer before\n// the replacements subscribe) can momentarily drop the refcount to zero. A bare\n// teardown would make the next subscriber re-enter the cold-start path: the SWR\n// cache replays with `fromCache: true`, which emits `ready: false` and flips the\n// form read-only until fresh snapshots arrive — silently swallowing keystrokes\n// typed in that window. The invariant: a momentary zero-subscriber gap on a\n// warm, healthy document pair must never surface as `ready: false`.\nconst TEARDOWN_GRACE_PERIOD = 1_000\n\n/** @internal */\nexport const editState = memoize(\n (\n ctx: {\n client: SanityClient\n schema: Schema\n /**\n * @deprecated Does nothing. Preserved to avoid breaking changes.\n * Will be removed in the next major version.\n */\n serverActionsEnabled?: Observable<boolean>\n extraOptions?: DocumentStoreExtraOptions\n },\n idPair: IdPair,\n typeName: string,\n ): Observable<EditStateFor> => {\n const initialState = getInitialEditState(ctx.schema, idPair, typeName)\n const {liveEdit, liveEditSchemaType, scopeId} = initialState\n\n return snapshotPair(ctx.client, idPair, typeName, undefined, ctx.extraOptions).pipe(\n switchMap((versions) =>\n combineLatest([\n versions.draft.snapshots$,\n versions.published.snapshots$,\n versions.transactionsPendingEvents$.pipe(\n map((ev: PendingMutationsEvent) => (ev.phase === 'begin' ? LOCKED : NOT_LOCKED)),\n startWith(NOT_LOCKED),\n ),\n typeof versions.version === 'undefined' ? of(null) : versions.version.snapshots$,\n ]),\n ),\n swr(`${idPair.publishedId}-${idPair.draftId}-${idPair.versionId}`),\n measureFirstEmission(\n (durationMs, {fromCache, value: [draftSnapshot, publishedSnapshot, versionSnapshot]}) => {\n ctx.extraOptions?.onDocumentPairLoaded?.({\n durationMs,\n fromCache,\n hasPublished: Boolean(publishedSnapshot),\n hasDraft: Boolean(draftSnapshot),\n hasVersion: Boolean(versionSnapshot),\n })\n },\n ),\n // NOTE: `useEditState` deduplicates emissions downstream using shallow equality on\n // `draft`/`published`/`version` as well as `ready` and `transactionSyncLock`.\n // The map below preserves the snapshot identities and only allocates a new outer\n // wrapper while deriving those additional fields.\n //\n // A regression that clones any of these references — example. `draft: {...draftSnapshot}` — would silently\n // turn that dedupe into a no-op. We have regression tests for this.\n map(\n ({\n value: [draftSnapshot, publishedSnapshot, transactionSyncLock, versionSnapshot],\n fromCache,\n }) => ({\n id: idPair.publishedId,\n type: typeName,\n draft: draftSnapshot,\n published: publishedSnapshot,\n version: typeof idPair.versionId === 'undefined' ? null : versionSnapshot,\n liveEdit,\n liveEditSchemaType,\n ready: !fromCache,\n transactionSyncLock: fromCache ? null : transactionSyncLock,\n release: classifyRelease(versionSnapshot, scopeId),\n scopeId,\n }),\n ),\n startWith(initialState),\n // Unlike `publishReplay(1) + refCount()`, this resets the replay subject\n // when the pipeline is torn down, so a later cold subscriber won't get a\n // stale `ready: true` replayed before the cold-start emissions (and an\n // error won't be replayed forever).\n share({\n connector: () => new ReplaySubject(1),\n resetOnRefCountZero: () => timer(TEARDOWN_GRACE_PERIOD),\n }),\n )\n },\n (ctx, idPair, typeName) => memoizeKeyGen(ctx.client, idPair, typeName),\n)\n","import {type SanityClient} from '@sanity/client'\nimport {\n isGlobalDocumentReference,\n isReference,\n type SanityDocument,\n type Schema,\n type ValidationContext,\n type ValidationMarker,\n type CurrentUser,\n} from '@sanity/types'\nimport {evaluateDocumentObservable} from '@sanity/validation/_internal'\nimport {reduce as reduceJSON} from 'json-reduce'\nimport {\n asyncScheduler,\n combineLatest,\n concat,\n defer,\n from,\n lastValueFrom,\n type Observable,\n of,\n timer,\n} from 'rxjs'\nimport {exhaustMapWithTrailing} from 'rxjs-exhaustmap-with-trailing'\nimport {\n distinct,\n distinctUntilChanged,\n first,\n groupBy,\n map,\n mergeMap,\n scan,\n shareReplay,\n skip,\n throttleTime,\n} from 'rxjs/operators'\n\nimport {type SourceClientOptions} from '../config/types'\nimport {type LocaleSource} from '../i18n/types'\nimport {type DocumentPreviewStore} from '../preview/documentPreviewStore'\nimport {getVersionFromId} from '../util/draftUtils'\nimport {shallowEquals} from '../util/shallowEquals'\n\n/**\n * @hidden\n * @beta */\nexport interface ValidationStatus {\n isValidating: boolean\n validation: ValidationMarker[]\n revision?: string\n}\n\nconst INITIAL_VALIDATION_STATUS: ValidationStatus = {\n isValidating: true,\n validation: [],\n}\n\nfunction findReferenceIds(obj: any): Set<string> {\n return reduceJSON(\n obj,\n (acc, node) => {\n if (isReference(node) && !isGlobalDocumentReference(node)) {\n acc.add(node._ref)\n }\n return acc\n },\n new Set<string>(),\n )\n}\n\nconst EMPTY_VALIDATION: ValidationMarker[] = []\n\ntype GetDocumentExists = NonNullable<ValidationContext['getDocumentExists']>\n\nconst listenDocumentExists = (\n observeDocumentAvailability: DocumentPreviewStore['unstable_observeDocumentPairAvailability'],\n id: string,\n versionId: string | undefined,\n): Observable<boolean> =>\n observeDocumentAvailability(id, {version: versionId}).pipe(\n map(({published, version}) => {\n if (!version?.available && version?.reason === 'VERSION_DELETED') {\n return false\n }\n\n return published.available || version?.available || false\n }),\n )\n\n// throttle delay for referenced document updates (i.e. time between responding to changes in referenced documents)\nconst REF_UPDATE_DELAY = 1000\n\nfunction shareLatestWithRefCount<T>() {\n return shareReplay<T>({bufferSize: 1, refCount: true})\n}\n\n/**\n * @internal\n * Takes an observable of a document and validates it, including any references in the document.\n * */\nexport function validateDocumentWithReferences(\n ctx: {\n getClient: (options: SourceClientOptions) => SanityClient\n observeDocumentPairAvailability: DocumentPreviewStore['unstable_observeDocumentPairAvailability']\n schema: Schema\n i18n: LocaleSource\n currentUser?: Omit<CurrentUser, 'role'> | null\n },\n document$: Observable<SanityDocument | null | undefined>,\n // whether to require all references to exist as published documents\n // set to false to allow references to versions as long they exist in the same bundle\n requirePublishedReferences: boolean,\n): Observable<ValidationStatus> {\n const referenceIds$ = document$.pipe(\n map((document) => findReferenceIds(document)),\n mergeMap((ids) => from(ids)),\n )\n\n const versionId$ = document$.pipe(distinctUntilChanged())\n\n // Note: we only use this to trigger a re-run of validation when a referenced document is published/unpublished\n const referenceExistence$ = combineLatest([versionId$, referenceIds$]).pipe(\n groupBy(([_, referenceId]) => referenceId, {duration: () => timer(1000 * 60 * 30)}),\n mergeMap((refIds$) =>\n refIds$.pipe(\n distinct(),\n mergeMap(([document, referenceId]) => {\n // listen for reference document existence\n // if we're require the referenced document to be published: pass undefined as version id\n // as that will check for existence of published document\n // Otherwise, pass the version of the referencing document\n // to validate that the version exists in the same bundle\n const versionId = requirePublishedReferences\n ? undefined\n : getVersionFromId(document?._id || '')\n return listenDocumentExists(\n ctx.observeDocumentPairAvailability,\n referenceId,\n versionId,\n ).pipe(map((result) => [referenceId, result] as const))\n }),\n ),\n ),\n scan((acc: Record<string, boolean>, [id, result]): Record<string, boolean> => {\n if (acc[id] === result) {\n return acc\n }\n return {...acc, [id]: result}\n }, {}),\n distinctUntilChanged(shallowEquals),\n shareLatestWithRefCount(),\n )\n\n // Provided to individual validation functions to support using existence of a weakly referenced document\n // as part of the validation rule (used by references in place)\n const getDocumentExists: GetDocumentExists = ({id}) =>\n lastValueFrom(\n referenceExistence$.pipe(\n // If the id is not present as key in the `referenceExistence` map it means it's existence status\n // isn't yet loaded, so we want to wait until it is\n first((referenceExistence) => id in referenceExistence),\n map((referenceExistence) => referenceExistence[id]),\n ),\n )\n\n const referenceDocumentUpdates$ = referenceExistence$.pipe(\n // we'll skip the first emission since the document already gets an initial validation pass\n // we're only interested in updates in referenced documents after that\n skip(1),\n throttleTime(REF_UPDATE_DELAY, asyncScheduler, {leading: true, trailing: true}),\n )\n\n return combineLatest([document$, concat(of(null), referenceDocumentUpdates$)]).pipe(\n map(([document]) => document),\n exhaustMapWithTrailing((document) => {\n return defer(() => {\n if (!document?._type) {\n return of({validation: EMPTY_VALIDATION, isValidating: false})\n }\n return concat(\n of({isValidating: true, revision: document._rev}),\n evaluateDocumentObservable({\n document,\n getClient: ctx.getClient,\n getDocumentExists,\n i18n: ctx.i18n,\n schema: ctx.schema,\n environment: 'studio',\n currentUser: ctx.currentUser,\n }).pipe(map((result) => ({validation: result.markers, isValidating: false}))),\n )\n })\n }),\n scan((acc, next) => ({...acc, ...next}), INITIAL_VALIDATION_STATUS),\n shareLatestWithRefCount(),\n )\n}\n","import {\n type ValidateDocumentWorkspaceOptions,\n validateDocumentWithWorkspace,\n} from '@sanity/validation'\n\nexport {\n validateDocumentWithReferences,\n type ValidationStatus,\n} from './validateDocumentWithReferences'\n\n/** @beta */\nexport type ValidateDocumentOptions = ValidateDocumentWorkspaceOptions\n\n/**\n * Validates a document against the schema in the given workspace.\n *\n * @beta\n */\nexport function validateDocument(options: ValidateDocumentOptions) {\n // oxlint-disable-next-line typescript/no-deprecated -- wraps the compatibility API without deprecating the stable Studio export\n return validateDocumentWithWorkspace(options)\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type CurrentUser, type Schema} from '@sanity/types'\nimport omit from 'lodash-es/omit.js'\nimport {asyncScheduler, combineLatest, type Observable} from 'rxjs'\nimport {distinctUntilChanged, map, shareReplay, throttleTime} from 'rxjs/operators'\n\nimport {type SourceClientOptions} from '../../../config/types'\nimport {type LocaleSource} from '../../../i18n/types'\nimport {type DraftsModelDocumentAvailability} from '../../../preview/types'\nimport {type DocumentVariantType} from '../../../util/getDocumentVariantType'\nimport {shallowEquals} from '../../../util/shallowEquals'\nimport {validateDocumentWithReferences, type ValidationStatus} from '../../../validation'\nimport {type DocumentStoreExtraOptions} from '../getPairListener'\nimport {type IdPair} from '../types'\nimport {memoize} from '../utils/createMemoizer'\nimport {editState} from './editState'\nimport {memoizeKeyGen} from './memoizeKeyGen'\n\n// throttle delay for document updates (i.e. time between responding to changes in the current document)\nconst DOC_UPDATE_DELAY = 200\n\nfunction shareLatestWithRefCount<T>() {\n return shareReplay<T>({bufferSize: 1, refCount: true})\n}\n\n/** @internal */\nexport const validation = memoize(\n (\n ctx: {\n client: SanityClient\n getClient: (options: SourceClientOptions) => SanityClient\n observeDocumentPairAvailability: (id: string) => Observable<DraftsModelDocumentAvailability>\n schema: Schema\n i18n: LocaleSource\n /**\n * @deprecated Does nothing. Preserved to avoid breaking changes.\n * Will be removed in the next major version.\n */\n serverActionsEnabled?: Observable<boolean>\n pairListenerOptions?: DocumentStoreExtraOptions\n currentUser?: Omit<CurrentUser, 'role'> | null\n },\n {draftId, publishedId, versionId}: IdPair,\n typeName: string,\n validationTarget: DocumentVariantType,\n validatePublishedReferences: boolean,\n ): Observable<ValidationStatus> => {\n const document$ = editState(ctx, {draftId, publishedId, versionId}, typeName).pipe(\n map((state) => {\n const {version, draft, published} = state\n\n if (validationTarget === 'draft') return draft\n if (validationTarget === 'version') return version\n return published\n }),\n throttleTime(DOC_UPDATE_DELAY, asyncScheduler, {trailing: true}),\n )\n\n const documentToValidate$ = document$.pipe(\n distinctUntilChanged((prev, next) => {\n if (prev?._rev === next?._rev) {\n return true\n }\n // _rev and _updatedAt may change without other fields changing (due to a limitation in mutator)\n // so only pass on documents if _other_ attributes changes\n return shallowEquals(omit(prev, '_rev', '_updatedAt'), omit(next, '_rev', '_updatedAt'))\n }),\n shareLatestWithRefCount(),\n )\n\n /**\n * When a local mutation is applied, the document content updates immediately\n * but the `_rev` stays the same. When the server later confirms the\n * mutation, a new `_rev` arrives, but since the content hasn't changed (it was\n * already applied), `documentToValidate$` correctly skips re-validation due to\n * the `shallowEquals` check above.\n *\n * However, the `revision` field exposed in `ValidationStatus` must still reflect\n * the latest `_rev` from the server. If it doesn't, consumers that compare\n * `validationStatus.revision` against the current document `_rev` (e.g. the\n * publish action's scheduled-publish guard) will see a stale revision and may\n * never consider validation \"complete\" for the current document state.\n *\n * To fix this, we track `documentRevision$` separately from `documentToValidate$`\n * and always override the revision in the emitted validation status.\n */\n const documentRevision$ = document$.pipe(map((document) => document?._rev))\n\n return combineLatest([\n documentRevision$,\n validateDocumentWithReferences(ctx, documentToValidate$, validatePublishedReferences),\n ]).pipe(\n map(([revision, validationStatus]) => {\n return {...validationStatus, revision}\n }),\n )\n },\n (ctx, idPair, typeName, validationTarget, validatePublishedReferences) => {\n // Use the actual document ID being validated in the cache key for explicitness\n const documentId =\n validationTarget === 'draft'\n ? idPair.draftId\n : validationTarget === 'version'\n ? idPair.versionId\n : idPair.publishedId\n // Include the user id so an in-place user switch gets its own cache entry;\n // the module-level memo cache is never cleared, so without this a new user\n // would replay the previous user's validation result.\n const userId = ctx.currentUser?.id ?? ''\n return `${memoizeKeyGen(ctx.client, idPair, typeName)}-${documentId}-${validatePublishedReferences}-${userId}`\n },\n)\n","import {type InitialValueResolverContext, type SanityDocumentLike, type Schema} from '@sanity/types'\nimport {from, merge, type Observable, of} from 'rxjs'\nimport {\n catchError,\n debounceTime,\n distinctUntilChanged,\n filter,\n map,\n scan,\n startWith,\n switchMap,\n timeout,\n} from 'rxjs/operators'\n\nimport {type DocumentPreviewStore} from '../../../preview/documentPreviewStore'\nimport {RESOLVE_INITIAL_VALUE_TIMEOUT_MS, resolveInitialValue} from '../../../templates/resolve'\nimport {type Template} from '../../../templates/types'\nimport {getDraftId, getPublishedId} from '../../../util/draftUtils'\nimport {\n type InitialValueErrorMsg,\n type InitialValueLoadingMsg,\n type InitialValueMsg,\n type InitialValueSuccessMsg,\n} from './types'\n\n/**\n * @hidden\n * @beta */\nexport interface InitialValueOptions {\n documentId: string\n documentType: string\n templateName?: string\n templateParams?: Record<string, any>\n}\n\nconst LOADING_MSG: InitialValueLoadingMsg = {type: 'loading'}\n\n/**\n * @internal\n */\nexport function getInitialValueStream(\n schema: Schema,\n initialValueTemplates: Template[],\n documentPreviewStore: DocumentPreviewStore,\n opts: InitialValueOptions,\n context: InitialValueResolverContext,\n): Observable<InitialValueMsg> {\n const draft$ = documentPreviewStore.observePaths(\n {_type: 'reference', _ref: getDraftId(opts.documentId)},\n ['_type'],\n )\n\n const published$ = documentPreviewStore.observePaths(\n {_type: 'reference', _ref: getPublishedId(opts.documentId)},\n ['_type'],\n )\n\n const value$ = merge(\n draft$.pipe(map((draft) => ({draft}))),\n published$.pipe(map((published) => ({published}))),\n ).pipe(\n scan((prev, res) => ({...prev, ...res}), {}),\n // Wait until we know the state of both draft and published\n filter((res) => 'draft' in res && 'published' in res),\n map((res: any) => res.draft || res.published),\n // Only update if we didn't previously have a document but we now do\n distinctUntilChanged((prev, next) => Boolean(prev) !== Boolean(next)),\n // Prevent rapid re-resolving when transitioning between different templates\n debounceTime(25),\n )\n\n return value$.pipe(\n switchMap((document): Observable<InitialValueMsg> => {\n // Already exists, so no initial value is needed\n if (document) {\n return of({type: 'success', value: null})\n }\n\n if (!opts.templateName) {\n // @todo: Make sure this is the correct behavior\n return of({type: 'success', value: null})\n }\n\n const template = initialValueTemplates.find((t) => t.id === opts.templateName)\n\n if (!template) {\n console.warn('Template \"%s\" not defined, using empty initial value', opts.templateName)\n return of({type: 'success', value: null})\n }\n\n const resolved$ = from(\n resolveInitialValue(schema, template, opts.templateParams, context),\n ).pipe(\n // A resolver whose request is parked (network/CORS) never settles —\n // time it out so the failure surfaces rather than hanging the editor.\n timeout({first: RESOLVE_INITIAL_VALUE_TIMEOUT_MS}),\n map((initialValue): InitialValueSuccessMsg => ({\n type: 'success',\n // The resolver returns an arbitrary record; by contract it's a\n // document-like value (the template's `_type` was merged in).\n value: initialValue as SanityDocumentLike,\n })),\n catchError((resolveError: Error) => {\n // oxlint-disable no-console\n console.group('Failed to resolve initial value')\n console.error(resolveError)\n console.error('Template ID: %s', opts.templateName)\n console.error('Parameters: %o', opts.templateParams)\n console.groupEnd()\n // oxlint-enable no-console\n\n // Carry the original error so the consumer can classify it\n // (a network/5xx failure in a resolver's `client.fetch` is\n // delegated to the studio's request-error dialog) and re-throwing\n // resolver bugs stay caller-domain.\n const msg: InitialValueErrorMsg = {type: 'error', error: resolveError}\n return of(msg)\n }),\n )\n\n return merge(of<InitialValueMsg>(LOADING_MSG), resolved$)\n }),\n\n startWith(LOADING_MSG),\n distinctUntilChanged(),\n )\n}\n","import {type ClientPerspective, type SanityClient} from '@sanity/client'\nimport {asyncScheduler, defer, merge, type Observable, of, partition, throwError, timer} from 'rxjs'\nimport {exhaustMapWithTrailing} from 'rxjs-exhaustmap-with-trailing'\nimport {filter, mergeMap, share, take, throttleTime} from 'rxjs/operators'\n\nimport {versionedClient} from '../../studioClient'\nimport {variantApiVersion} from '../../variants/util/variantApiVersion'\nimport {type MutationEvent, type ReconnectEvent, type WelcomeEvent} from './types'\n\n/** @internal */\nexport type ListenQueryParams = Record<string, string | number | boolean | string[]>\n\n/**\n * @hidden\n * @beta */\nexport interface ListenQueryOptions {\n tag?: string\n apiVersion?: string\n perspective?: ClientPerspective\n /**\n * The selected editing variant as a bare variant id. When set, documents are resolved as seen\n * through that variant, on top of `perspective`.\n */\n variant?: string\n throttleTime?: number\n transitions?: ('update' | 'appear' | 'disappear')[]\n}\n\nconst fetch = (\n client: SanityClient,\n query: string,\n params: ListenQueryParams,\n options: ListenQueryOptions,\n) =>\n defer(() =>\n versionedClient(client, variantApiVersion(options.variant)).observable.fetch(query, params, {\n tag: options.tag,\n filterResponse: true,\n perspective: options.perspective,\n variant: options.variant,\n }),\n )\n\nconst listen = (\n client: SanityClient,\n query: string,\n params: ListenQueryParams,\n options: ListenQueryOptions,\n) =>\n defer(() =>\n client.listen(query, params, {\n events: ['welcome', 'mutation', 'reconnect'],\n includeResult: false,\n visibility: 'query',\n includeAllVersions: true,\n tag: options.tag,\n }),\n ) as Observable<ReconnectEvent | WelcomeEvent | MutationEvent>\n\nfunction isWelcomeEvent(\n event: MutationEvent | ReconnectEvent | WelcomeEvent,\n): event is WelcomeEvent {\n return event.type === 'welcome'\n}\n\n/** @internal */\nexport function listenQuery(\n client: SanityClient,\n query: string | {fetch: string; listen: string},\n params: ListenQueryParams = {},\n options: ListenQueryOptions = {},\n): Observable<any> {\n const fetchQuery = typeof query === 'string' ? query : query.fetch\n const listenerQuery = typeof query === 'string' ? query : query.listen\n\n const events$ = listen(client, listenerQuery, params, options).pipe(\n mergeMap((ev, i) => {\n const isFirst = i === 0\n if (isFirst && !isWelcomeEvent(ev)) {\n // if the first event is not welcome, it is most likely a reconnect and\n // if it's not a reconnect something is very wrong\n return throwError(\n () =>\n new Error(\n ev.type === 'reconnect'\n ? 'Could not establish EventSource connection'\n : `Received unexpected type of first event \"${ev.type}\"`,\n ),\n )\n }\n return of(ev)\n }),\n share(),\n )\n\n const [welcome$, mutationAndReconnect$] = partition(events$, isWelcomeEvent)\n const isRelevantEvent = (event: MutationEvent | ReconnectEvent | WelcomeEvent): boolean => {\n if (!options.transitions || event.type !== 'mutation') {\n return true\n }\n\n return options.transitions.includes(event.transition)\n }\n\n const doFetch = () => fetch(client, fetchQuery, params, options)\n\n return merge(\n welcome$.pipe(take(1)),\n mutationAndReconnect$.pipe(\n filter(isRelevantEvent),\n throttleTime(options.throttleTime || 1000, asyncScheduler, {leading: true, trailing: true}),\n ),\n ).pipe(\n exhaustMapWithTrailing((event) => {\n if (event.type === 'mutation' && event.visibility !== 'query') {\n // Even though the listener request specifies visibility=query, the events are not guaranteed to be delivered with visibility=query\n // If the event we are responding to arrives with visibility != query, we add a little delay to allow for the updated document to be available for queries\n // See https://www.sanity.io/docs/listening#visibility-c4786e55c3ff\n return timer(1200).pipe(mergeMap(doFetch))\n }\n return doFetch()\n }),\n )\n}\n","import {type DocumentPairTarget} from './types'\n\n/**\n * Normalizes the `version` parameter accepted by the document pair APIs\n * (`useDocumentOperation`, `pair.editOperations`) to a {@link DocumentPairTarget}.\n *\n * A bare string is back-compat shorthand for a plain version target — the scope id, i.e. the\n * `<scopeId>` segment of `versions.<scopeId>.<groupId>` (a release or agent/anonymous bundle\n * name); target objects pass through by reference, and `undefined` means the base\n * draft/published pair.\n *\n */\nexport function normalizeDocumentPairTarget(\n version: string | DocumentPairTarget | undefined,\n): DocumentPairTarget | undefined {\n if (typeof version === 'string') {\n return {kind: 'version', scopeId: version}\n }\n return version\n}\n\n/**\n * The scope id (the `<scopeId>` segment of `versions.<scopeId>.<groupId>`) the pair should check\n * out for a target, or `undefined` when the base draft/published pair applies. Guarded kinds\n * (`target-missing`, `unresolved`) never reach pair checkout and yield `undefined`.\n *\n */\nexport function getPairTargetScopeId(target: DocumentPairTarget | undefined): string | undefined {\n if (target?.kind === 'version' || target?.kind === 'variant') {\n return target.scopeId\n }\n return undefined\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type Observable, of} from 'rxjs'\n\nimport {getPublishedId} from '../../util/draftUtils'\n\nexport function resolveTypeForDocument(\n client: SanityClient,\n id: string,\n specifiedType = '*',\n): Observable<string> {\n // if is resolved document type\n if (specifiedType && specifiedType !== '*') {\n return of(specifiedType)\n }\n\n const query = '*[sanity::versionOf($publishedId)][0]._type'\n\n return client.observable.fetch(\n query,\n {publishedId: getPublishedId(id)},\n {\n tag: 'document.resolve-type',\n },\n )\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type CurrentUser, type InitialValueResolverContext, type Schema} from '@sanity/types'\nimport {type Observable, of} from 'rxjs'\nimport {filter, map} from 'rxjs/operators'\n\nimport {type SourceClientOptions} from '../../config/types'\nimport {type LocaleSource} from '../../i18n/types'\nimport {type DocumentPreviewStore} from '../../preview/documentPreviewStore'\nimport {DEFAULT_STUDIO_CLIENT_OPTIONS} from '../../studioClient'\nimport {type Template} from '../../templates/types'\nimport {\n getPublishedId,\n getVersionFromId,\n isDraftId,\n isVersionId,\n getIdPair,\n} from '../../util/draftUtils'\nimport {getDocumentVariantType} from '../../util/getDocumentVariantType'\nimport {type ValidationStatus} from '../../validation'\nimport {type HistoryStore} from '../history/createHistoryStore'\nimport {\n checkoutPair,\n type CommitError,\n type DocumentVersionEvent,\n type Pair,\n} from './document-pair/checkoutPair'\nimport {commitErrorStatus} from './document-pair/commitErrorStatus'\nimport {consistencyStatus} from './document-pair/consistencyStatus'\nimport {documentEvents} from './document-pair/documentEvents'\nimport {editOperations} from './document-pair/editOperations'\nimport {editState, type EditStateFor} from './document-pair/editState'\nimport {\n type OperationError,\n operationEvents,\n type OperationSuccess,\n} from './document-pair/operationEvents'\nimport {GUARDED, TARGET_NOT_FOUND_OPERATIONS} from './document-pair/operations/helpers'\nimport {type OperationsAPI} from './document-pair/operations/types'\nimport {validation} from './document-pair/validation'\nimport {type DocumentStoreExtraOptions} from './getPairListener'\nimport {getInitialValueStream, type InitialValueOptions} from './initialValue/initialValue'\nimport {type InitialValueMsg} from './initialValue/types'\nimport {listenQuery, type ListenQueryOptions} from './listenQuery'\nimport {getPairTargetScopeId, normalizeDocumentPairTarget} from './normalizeDocumentPairTarget'\nimport {resolveTypeForDocument} from './resolveTypeForDocument'\nimport {type DocumentPairTarget, type IdPair} from './types'\n\n/**\n * @hidden\n * @beta */\nexport type QueryParams = Record<string, string | number | boolean | string[]>\n\nfunction getIdPairFromPublished(publishedId: string, version?: string): IdPair {\n if (version === 'published' || version === 'drafts') {\n throw new Error('Version Id cannot be \"published\" or \"drafts\"')\n }\n if (isVersionId(publishedId)) {\n throw new Error('editOpsOf does not expect a version id.')\n }\n if (isDraftId(publishedId)) {\n throw new Error('editOpsOf does not expect a draft id.')\n }\n\n return getIdPair(publishedId, {version})\n}\n\n/**\n * @hidden\n * @beta */\nexport interface DocumentStore {\n /**\n * Checks out a document (with its published and draft version) for real-time editing.\n * Note that every call to this function will open a new listener to the server.\n * It's recommended to use the helper functions on `pair` below which will re-use a single connection.\n *\n * @internal\n **/\n checkoutPair: (idPair: IdPair) => Pair\n initialValue: (\n opts: InitialValueOptions,\n context: InitialValueResolverContext,\n ) => Observable<InitialValueMsg>\n listenQuery: (\n query: string | {fetch: string; listen: string},\n params: QueryParams,\n options: ListenQueryOptions,\n ) => Observable<any>\n resolveTypeForDocument: (id: string, specifiedType?: string) => Observable<string>\n\n pair: {\n /** @internal */\n commitErrorStatus: (\n publishedId: string,\n type: string,\n version?: string,\n ) => Observable<CommitError | undefined>\n consistencyStatus: (publishedId: string, type: string, version?: string) => Observable<boolean>\n /** @internal */\n documentEvents: (\n publishedId: string,\n type: string,\n version?: string,\n ) => Observable<DocumentVersionEvent>\n /**\n * @internal\n * `version` accepts either a plain version name (release/bundle) or a\n * {@link DocumentPairTarget}. The guarded target kinds (`unresolved`, `target-missing`) emit\n * a disabled operations API without checking out a pair, so operations can never reach the\n * base draft/published pair while a selected target is unresolved or has no document.\n */\n editOperations: (\n publishedId: string,\n type: string,\n version?: string | DocumentPairTarget,\n ) => Observable<OperationsAPI>\n editState: (publishedId: string, type: string, version?: string) => Observable<EditStateFor>\n operationEvents: (\n publishedId: string,\n type: string,\n ) => Observable<OperationSuccess | OperationError>\n validation: (\n validationTargetId: string,\n type: string,\n // Whether to require referenced documents to be published\n // if `true`, any reference to a document that's not published will yield a validation error\n // if `false`, any reference to a non-published document is ok as long as it's in the same bundle\n // as the document we're validating\n validatePublishedReferences: boolean,\n ) => Observable<ValidationStatus>\n }\n}\n\n/** @internal */\nexport interface DocumentStoreOptions {\n getClient: (options: SourceClientOptions) => SanityClient\n documentPreviewStore: DocumentPreviewStore\n historyStore: HistoryStore\n schema: Schema\n initialValueTemplates: Template[]\n i18n: LocaleSource\n /**\n * @deprecated Does nothing. Preserved to avoid breaking changes.\n * Will be removed in the next major version.\n */\n serverActionsEnabled?: Observable<boolean>\n extraOptions?: DocumentStoreExtraOptions\n currentUser?: Omit<CurrentUser, 'role'> | null\n}\n\n/** @internal */\nexport function createDocumentStore({\n getClient,\n documentPreviewStore,\n historyStore,\n initialValueTemplates,\n schema,\n i18n,\n extraOptions = {},\n currentUser,\n}: DocumentStoreOptions): DocumentStore {\n const observeDocumentPairAvailability =\n documentPreviewStore.unstable_observeDocumentPairAvailability\n\n // Note that we're both passing a shared `client` here which is used by the\n // internal operations, and a `getClient` method that we expose to user-land\n // for things like validations\n const client = getClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n\n const {\n onSyncErrorRecovery,\n onReportLatency,\n onSlowCommit,\n onReportMutationPerformance,\n onDocumentRebase,\n } = extraOptions\n const ctx = {\n client,\n getClient,\n observeDocumentPairAvailability,\n historyStore,\n schema,\n i18n,\n extraOptions,\n currentUser,\n }\n\n return {\n // Public API\n checkoutPair(idPair) {\n return checkoutPair(client, idPair, undefined, {\n onSyncErrorRecovery,\n onReportLatency,\n onSlowCommit,\n onReportMutationPerformance,\n onDocumentRebase,\n })\n },\n initialValue(opts, context) {\n return getInitialValueStream(\n schema,\n initialValueTemplates,\n documentPreviewStore,\n opts,\n context,\n )\n },\n listenQuery(query, params, listenQueryOptions) {\n return listenQuery(client, query, params, listenQueryOptions)\n },\n resolveTypeForDocument(id, specifiedType) {\n return resolveTypeForDocument(client, id, specifiedType)\n },\n pair: {\n commitErrorStatus(publishedId, type, version) {\n return commitErrorStatus(\n ctx.client,\n getIdPairFromPublished(publishedId, version),\n type,\n extraOptions,\n )\n },\n consistencyStatus(publishedId, type, version) {\n return consistencyStatus(\n ctx.client,\n getIdPairFromPublished(publishedId, version),\n type,\n extraOptions,\n )\n },\n documentEvents(publishedId, type, version) {\n return documentEvents(\n ctx.client,\n getIdPairFromPublished(publishedId, version),\n type,\n extraOptions,\n )\n },\n editOperations(publishedId, type, version) {\n const target = normalizeDocumentPairTarget(version)\n\n // Guarded targets never check out a pair. Branching here (before the memoized\n // `editOperations`) also keeps them out of `memoizeKeyGen`, which only keys on\n // `publishedId + versionId` and would collide these with the base pair.\n if (target?.kind === 'unresolved') {\n return of(GUARDED)\n }\n if (target?.kind === 'target-missing') {\n return of(TARGET_NOT_FOUND_OPERATIONS)\n }\n\n return editOperations(\n ctx,\n getIdPairFromPublished(publishedId, getPairTargetScopeId(target)),\n type,\n target,\n )\n },\n editState(publishedId, type, version) {\n const idPair = getIdPairFromPublished(publishedId, version)\n\n const edit = editState(ctx, idPair, type)\n return edit\n },\n operationEvents(publishedId, type) {\n return operationEvents({\n client,\n historyStore,\n schema,\n extraOptions,\n }).pipe(\n filter(\n (result) =>\n result.args.idPair.publishedId === publishedId && result.args.typeName === type,\n ),\n map((result): OperationSuccess | OperationError => {\n const {operationName, idPair} = result.args\n return result.type === 'success'\n ? {\n type: 'success',\n op: operationName,\n id: idPair.publishedId,\n idPair,\n }\n : {\n type: 'error',\n op: operationName,\n id: idPair.publishedId,\n error: result.error,\n idPair,\n }\n }),\n )\n },\n validation(validationTargetId, type, requirePublishedReferences) {\n const publishedId = getPublishedId(validationTargetId)\n const idPair = getIdPair(publishedId, {version: getVersionFromId(validationTargetId)})\n const validationTarget = getDocumentVariantType(validationTargetId)\n return validation(ctx, idPair, type, validationTarget, requirePublishedReferences)\n },\n },\n }\n}\n","import { asapScheduler, NEVER, Subject, timer, using, } from \"rxjs\";\r\nimport { scan, switchMap, tap } from \"rxjs/operators\";\r\nexport function refCountDelay(duration, scheduler = asapScheduler) {\r\n return (source) => {\r\n const connectable = source;\r\n let connectableSubscription = null;\r\n let connectorSubscription = null;\r\n const notifier = new Subject();\r\n const connector = notifier.pipe(scan((count, step) => count + step, 0), switchMap((count) => {\r\n if (count === 0) {\r\n return timer(duration, scheduler).pipe(tap(() => {\r\n if (connectableSubscription) {\r\n connectableSubscription.unsubscribe();\r\n connectableSubscription = null;\r\n }\r\n if (connectorSubscription) {\r\n connectorSubscription.unsubscribe();\r\n connectorSubscription = null;\r\n }\r\n }));\r\n }\r\n if (!connectableSubscription && count > 0) {\r\n return timer(0, scheduler).pipe(tap(() => {\r\n if (!connectableSubscription) {\r\n connectableSubscription = connectable.connect();\r\n }\r\n }));\r\n }\r\n return NEVER;\r\n }));\r\n return using(() => {\r\n if (!connectorSubscription) {\r\n connectorSubscription = connector.subscribe();\r\n }\r\n notifier.next(1);\r\n return { unsubscribe: () => notifier.next(-1) };\r\n }, () => source);\r\n };\r\n}\r\nexport const refCountAuditTime = refCountDelay;\r\n//# sourceMappingURL=refCountDelay.js.map","import {concat, fromEvent, of} from 'rxjs'\nimport {distinctUntilChanged, map} from 'rxjs/operators'\n\nconst DEBUG_PREFIX = '_debug_'\n\nconst hashchange$ = typeof window === 'undefined' ? of({}) : fromEvent(window, 'hashchange')\n\nexport const debugParams$ = concat(of(0), hashchange$).pipe(\n map(() => (typeof document === 'undefined' ? '#' : document.location.hash)),\n distinctUntilChanged(),\n map((hash) =>\n hash\n .slice(1)\n .split(';')\n .filter((p) => p.toLowerCase().startsWith(DEBUG_PREFIX))\n .map((param) => param.slice(DEBUG_PREFIX.length)),\n ),\n)\n\nexport const debugRolesParam$ = debugParams$.pipe(\n map((args) => args.find((arg) => arg.startsWith('roles='))),\n map(\n (arg) =>\n arg\n ?.split('roles=')[1]\n .split(',')\n .map((r) => r.trim()) || [],\n ),\n)\n","// NOTE: these example grants are used in other test files.\n// if you change this file, check to see if other files need to be updated too\nimport {type Grant} from '../types'\n\nexport const administrator: Grant[] = [\n {\n filter: '_id in path(\"**\")',\n permissions: ['read', 'create', 'history', 'update'],\n },\n]\n\nexport const editor: Grant[] = [\n {\n filter: '_id in path(\"**\")',\n permissions: ['read', 'create', 'history', 'update'],\n },\n]\n\nexport const developer: Grant[] = [\n {\n filter: '_id in path(\"**\")',\n permissions: ['read', 'create', 'history', 'update'],\n },\n]\n\nexport const contributor: Grant[] = [\n {\n filter: '_id in path(\"**\")',\n permissions: ['read'],\n },\n {\n filter: '_id in path(\"drafts.**\")',\n permissions: ['create', 'history', 'update'],\n },\n]\n\nexport const viewer: Grant[] = [\n {\n filter: '_id in path(\"**\")',\n permissions: ['read', 'history'],\n },\n]\n\nexport const requiresApproval: Grant[] = [\n {\n filter: '!locked',\n permissions: ['read', 'create', 'update'],\n },\n]\n\nexport const restricted: Grant[] = [\n {\n filter:\n '_id in path(\"drafts.**\") && _type in [\"stringsTest\", \"book\", \"author\", \"referenceTest\"]',\n permissions: ['read', 'create', 'history', 'update'],\n },\n {\n filter: '_id in path(\"**\")',\n permissions: ['read'],\n },\n]\n","import {map} from 'rxjs/operators'\n\nimport {debugRolesParam$} from '../../debugParams/debugParams'\nimport {type Grant} from '../types'\nimport * as grants from './exampleGrants'\nimport {type ExampleRoleName} from './exampleRoles'\n\nconst DEBUG_ROLE_GRANTS_MAP: Record<ExampleRoleName, Grant[]> = {\n // basic\n administrator: grants.administrator,\n editor: grants.editor,\n developer: grants.developer,\n contributor: grants.contributor,\n viewer: grants.viewer,\n\n // custom\n restricted: grants.restricted,\n requiresApproval: grants.requiresApproval,\n\n // legacy\n read: grants.viewer,\n write: grants.editor,\n}\n\n// todo: merge other resource keys(?)\nexport const debugGrants$ = debugRolesParam$.pipe(\n map((roles) => {\n if (!roles.length) return null\n\n return roles\n .filter((value) => Boolean(value) && value in DEBUG_ROLE_GRANTS_MAP)\n .flatMap((roleName: ExampleRoleName) => DEBUG_ROLE_GRANTS_MAP[roleName] || [])\n }),\n)\n","import {type SanityClient} from '@sanity/client'\nimport {type CurrentUser, type SanityDocument} from '@sanity/types'\nimport {evaluate, parse} from 'groq-js'\nimport {defer, of} from 'rxjs'\nimport {refCountDelay} from 'rxjs-etc/operators'\nimport {distinctUntilChanged, publishReplay, switchMap} from 'rxjs/operators'\n\nimport {shallowEquals} from '../../util/shallowEquals'\nimport {type StoreRequestErrorHandler} from '../requestErrorHandler'\nimport {debugGrants$} from './debug'\nimport {\n type DocumentValuePermission,\n type EvaluationParams,\n type Grant,\n type GrantsStore,\n type PermissionCheckResult,\n} from './types'\n\nasync function getDatasetGrants(\n client: SanityClient,\n projectId: string,\n dataset: string,\n errorHandler: StoreRequestErrorHandler | undefined,\n): Promise<Grant[]> {\n // `acl` stands for access control list and returns a list of grants\n const fetchGrants = () =>\n client.request<Grant[]>({\n url: `/projects/${projectId}/datasets/${dataset}/acl`,\n tag: 'acl.get',\n })\n\n // Every permission check depends on this read, so there is no local\n // recovery if it fails — delegate failures to the error handler when one\n // is provided. Retryable: it's an idempotent GET, safe to re-run.\n return errorHandler ? errorHandler.attempt(fetchGrants, {retryable: true}) : fetchGrants()\n}\n\nfunction getParams(userId: string | null): EvaluationParams {\n const params: EvaluationParams = {}\n\n if (userId !== null) {\n params.identity = userId\n }\n\n return params\n}\n\nconst PARSED_FILTERS_MEMO = new Map()\nasync function matchesFilter(userId: string | null, filter: string, document: SanityDocument) {\n if (!PARSED_FILTERS_MEMO.has(filter)) {\n // note: it might be tempting to also memoize the result of the evaluation here,\n // Currently these filters are typically evaluated whenever a document change, which means they will be evaluated\n // quite frequently with different versions of the document. There might be some gains in finding out which subset of document\n // properties to use as key (e.g. by looking at the parsed filter and see what properties the filter cares about)\n // But as always, it's worth considering if the complexity/memory usage is worth the potential perf gain…\n PARSED_FILTERS_MEMO.set(filter, parse(`*[${filter}]`))\n }\n const parsed = PARSED_FILTERS_MEMO.get(filter)\n\n const evalParams = getParams(userId)\n const {identity} = evalParams\n const params: Record<string, unknown> = {...evalParams}\n const data = await (await evaluate(parsed, {dataset: [document], identity, params})).get()\n return data?.length === 1\n}\ninterface GrantsStoreOptionsCurrentUser {\n client: SanityClient\n /**\n * Optional handler for failures of requests made by the store. When\n * omitted, request failures propagate to the permission streams.\n */\n errorHandler?: StoreRequestErrorHandler\n /**\n * @deprecated The `currentUser` option is deprecated. Use `userId` instead.\n */\n currentUser: CurrentUser | null\n}\n\ninterface GrantsStoreOptionsUserId {\n client: SanityClient\n /**\n * Optional handler for failures of requests made by the store. When\n * omitted, request failures propagate to the permission streams.\n */\n errorHandler?: StoreRequestErrorHandler\n userId: string | null\n}\n\n/** @internal */\nexport type GrantsStoreOptions = GrantsStoreOptionsCurrentUser | GrantsStoreOptionsUserId\n\n/** @internal */\nexport function createGrantsStore(opts: GrantsStoreOptions): GrantsStore {\n const {client, errorHandler} = opts\n const versionedClient = client.withConfig({apiVersion: '2021-06-07'})\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const userId = 'userId' in opts ? opts.userId : opts?.currentUser?.id || null\n\n const datasetGrants$ = defer(() => of(versionedClient.config())).pipe(\n switchMap(({projectId, dataset}) => {\n if (!projectId || !dataset) {\n throw new Error('Missing projectId or dataset')\n }\n return getDatasetGrants(versionedClient, projectId, dataset, errorHandler)\n }),\n )\n\n const currentUserDatasetGrants = debugGrants$.pipe(\n switchMap((debugGrants) => (debugGrants ? of(debugGrants) : datasetGrants$)),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n publishReplay(1),\n refCountDelay(1000),\n )\n\n return {\n checkDocumentPermission(permission: DocumentValuePermission, document: SanityDocument) {\n return currentUserDatasetGrants.pipe(\n switchMap((grants) => grantsPermissionOn(userId, grants, permission, document)),\n distinctUntilChanged(shallowEquals),\n )\n },\n }\n}\n\n/**\n * @internal\n * Takes a grants object, a permission and a document\n * checks whether the permission is granted for the given document\n */\nexport async function grantsPermissionOn(\n userId: string | null,\n grants: Grant[],\n permission: DocumentValuePermission,\n document: SanityDocument | null,\n): Promise<PermissionCheckResult> {\n if (!document) {\n // we say it's granted if null due to initial states\n return {granted: true, reason: 'Null document, nothing to check'}\n }\n\n if (!grants.length) {\n return {granted: false, reason: 'No document grants'}\n }\n\n const matchingGrants: Grant[] = []\n\n for (const grant of grants) {\n if (await matchesFilter(userId, grant.filter, document)) {\n matchingGrants.push(grant)\n }\n }\n\n const foundMatch = matchingGrants.some((grant) => grant.permissions.some((p) => p === permission))\n\n return {\n granted: foundMatch,\n reason: foundMatch ? `Matching grant` : `No matching grants found`,\n }\n}\n","/** @internal */\nexport const isDev = process.env.NODE_ENV !== 'production'\n\n/** @internal */\nexport const isProd = !isDev\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type MendozaEffectPair, type MendozaPatch} from '@sanity/types'\n\nimport {type Chunk, type ChunkType} from '../../../field/types'\nimport {type Transaction} from './types'\n\nfunction canMergeEdit(type: ChunkType) {\n return type === 'create' || type === 'editDraft'\n}\n\nconst CHUNK_WINDOW = 5 * 60 * 1000 // 5 minutes\n\nfunction isWithinMergeWindow(a: string, b: string) {\n return Date.parse(b) - Date.parse(a) < CHUNK_WINDOW\n}\n\nexport function mergeChunk(left: Chunk, right: Chunk): Chunk | [Chunk, Chunk] {\n if (left.end !== right.start) throw new Error('chunks are not next to each other')\n\n // TODO: How to detect first squash/create\n\n const draftState = combineState(left.draftState, right.draftState)\n const publishedState = combineState(left.publishedState, right.publishedState)\n\n if (left.type === 'delete' && right.type === 'editDraft') {\n return [left, {...right, type: 'create', draftState, publishedState}]\n }\n\n // Convert deletes into either discardDraft or unpublish depending on what's been deleted.\n if (right.type === 'delete') {\n if (draftState === 'missing' && publishedState === 'present') {\n return [left, {...right, type: 'discardDraft', draftState, publishedState}]\n }\n\n if (draftState === 'present' && publishedState === 'missing') {\n return [left, {...right, type: 'unpublish', draftState, publishedState}]\n }\n }\n\n if (\n canMergeEdit(left.type) &&\n right.type === 'editDraft' &&\n isWithinMergeWindow(left.endTimestamp, right.startTimestamp)\n ) {\n const authors = new Set<string>()\n for (const author of left.authors) authors.add(author)\n for (const author of right.authors) authors.add(author)\n\n return {\n index: 0,\n id: right.id,\n type: left.type,\n start: left.start,\n end: right.end,\n startTimestamp: left.startTimestamp,\n endTimestamp: right.endTimestamp,\n authors,\n draftState,\n publishedState,\n }\n }\n\n return [left, {...right, draftState, publishedState}]\n}\n\ntype ChunkState = 'unedited' | 'deleted' | 'upsert'\nfunction getChunkState(effect?: MendozaEffectPair): ChunkState {\n const modified = Boolean(effect)\n const deleted = effect && isDeletePatch(effect?.apply)\n\n if (deleted) {\n return 'deleted'\n }\n\n if (modified) {\n return 'upsert'\n }\n\n return 'unedited'\n}\n\n/*\n * getChunkType tries to determine what effect the given transaction had on the document\n * More information about the logic can be found here https://github.com/sanity-io/sanity/pull/2633#issuecomment-886461812\n *\n * | | draft unedited | draft deleted | draft upsert |\n * |--------------------|----------------|---------------|--------------|\n * | published unedited | X | delete | editDraft |\n * | published deleted | delete | delete | delete |\n * | published upsert | liveEdit | publish | liveEdit |\n */\nfunction getChunkType(transaction: Transaction): ChunkType {\n const draftState = getChunkState(transaction.draftEffect)\n const publishedState = getChunkState(transaction.publishedEffect)\n\n if (publishedState === 'unedited') {\n if (draftState === 'deleted') {\n return 'delete'\n }\n\n if (draftState === 'upsert') {\n return 'editDraft'\n }\n }\n\n if (publishedState === 'deleted') {\n return 'delete'\n }\n\n if (publishedState === 'upsert') {\n if (draftState === 'unedited') {\n return 'editLive'\n }\n\n if (draftState === 'deleted') {\n return 'publish'\n }\n\n if (draftState === 'upsert') {\n return 'editLive'\n }\n }\n\n return 'editLive'\n}\n\nexport function chunkFromTransaction(transaction: Transaction): Chunk {\n const modifiedDraft = Boolean(transaction.draftEffect)\n const modifiedPublished = Boolean(transaction.publishedEffect)\n\n const draftDeleted = transaction.draftEffect && isDeletePatch(transaction.draftEffect.apply)\n const publishedDeleted =\n transaction.publishedEffect && isDeletePatch(transaction.publishedEffect.apply)\n\n const type = getChunkType(transaction)\n\n return {\n index: 0,\n id: transaction.id,\n type,\n start: transaction.index,\n end: transaction.index + 1,\n startTimestamp: transaction.timestamp,\n endTimestamp: transaction.timestamp,\n authors: new Set([transaction.author]),\n draftState: modifiedDraft ? (draftDeleted ? 'missing' : 'present') : 'unknown',\n publishedState: modifiedPublished ? (publishedDeleted ? 'missing' : 'present') : 'unknown',\n }\n}\n\nfunction combineState(\n left: 'present' | 'missing' | 'unknown',\n right: 'present' | 'missing' | 'unknown',\n) {\n return right === 'unknown' ? left : right\n}\n\nfunction isDeletePatch(patch: MendozaPatch): boolean {\n return patch[0] === 0 && patch[1] === null\n}\n","import {\n type ArrayInput,\n diffInput,\n type Input,\n type ObjectInput,\n type StringInput,\n wrap,\n} from '@sanity/diff'\nimport {type SanityDocument, type TransactionLogEventWithEffects} from '@sanity/types'\nimport {type incremental} from 'mendoza'\n\nimport {type Annotation} from '../../field/types'\nimport {type DocumentGroupEvent} from './types'\n\nexport type EventMeta = {\n transactionIndex: number\n event?: DocumentGroupEvent\n} | null\n\nfunction isSameAnnotation(a: Annotation, b: Annotation): boolean {\n if (a && b) {\n return a.author === b.author && a.timestamp === b.timestamp\n }\n\n if (!a && !b) {\n return true\n }\n\n return false\n}\n\nexport type AnnotationExtractor<T> = {\n fromValue(value: incremental.Value<T>): Annotation\n fromMeta(meta: T): Annotation\n}\n\nclass ArrayContentWrapper<T> implements ArrayInput<Annotation> {\n type = 'array' as const\n value: unknown[]\n length: number\n annotation: Annotation\n extractor: AnnotationExtractor<T>\n\n private content: incremental.ArrayContent<T>\n private elements: Input<Annotation>[] = []\n\n constructor(\n content: incremental.ArrayContent<T>,\n value: unknown[],\n annotation: Annotation,\n extractor: AnnotationExtractor<T>,\n ) {\n this.content = content\n this.value = value\n this.annotation = annotation\n this.extractor = extractor\n this.length = content.elements.length\n }\n\n at(idx: number) {\n if (idx >= this.length) throw new Error('out of bounds')\n const input = this.elements[idx]\n if (input) {\n return input\n }\n return (this.elements[idx] = wrapValue(\n this.content.elements[idx],\n this.value[idx],\n this.extractor,\n ))\n }\n\n annotationAt(idx: number): Annotation {\n const meta = this.content.metas[idx]\n return this.extractor.fromMeta(meta)\n }\n}\n\nclass ObjectContentWrapper<T> implements ObjectInput<Annotation> {\n type = 'object' as const\n value: Record<string, unknown>\n keys: string[]\n annotation: Annotation\n extractor: AnnotationExtractor<T>\n\n private content: incremental.ObjectContent<T>\n private fields: Record<string, Input<Annotation>> = {}\n\n constructor(\n content: incremental.ObjectContent<T>,\n value: Record<string, unknown>,\n annotation: Annotation,\n extractor: AnnotationExtractor<T>,\n ) {\n this.content = content\n this.value = value\n this.annotation = annotation\n this.extractor = extractor\n this.keys = Object.keys(content.fields)\n }\n\n get(key: string) {\n const input = this.fields[key]\n if (input) {\n return input\n }\n const value = this.content.fields[key]\n if (!value) return undefined\n return (this.fields[key] = wrapValue(value, this.value[key], this.extractor))\n }\n}\n\nclass StringContentWrapper<T> implements StringInput<Annotation> {\n type = 'string' as const\n value: string\n annotation: Annotation\n extractor: AnnotationExtractor<T>\n\n private content: incremental.StringContent<T>\n\n constructor(\n content: incremental.StringContent<T>,\n value: string,\n annotation: Annotation,\n extractor: AnnotationExtractor<T>,\n ) {\n this.content = content\n this.value = value\n this.annotation = annotation\n this.extractor = extractor\n }\n\n sliceAnnotation(start: number, end: number): {text: string; annotation: Annotation}[] {\n const result: {text: string; annotation: Annotation}[] = []\n let idx = 0\n\n function push(text: string, annotation: Annotation) {\n if (result.length > 0) {\n const lst = result[result.length - 1]\n if (isSameAnnotation(lst.annotation, annotation)) {\n lst.text += text\n return\n }\n }\n\n result.push({text, annotation})\n }\n\n for (const part of this.content.parts) {\n const length = part.value.length\n\n const subStart = Math.max(0, start - idx)\n if (subStart < length) {\n // The start of the slice is inside this part somewhere.\n\n // Figure out where the end is:\n const subEnd = Math.min(length, end - idx)\n\n // If the end of the slice is before this part, then we're guaranteed\n // that there are no more parts.\n if (subEnd <= 0) break\n\n push(part.value.slice(subStart, subEnd), this.extractor.fromValue(part))\n }\n\n idx += length\n }\n\n return result\n }\n}\n\nexport function wrapValue<T>(\n value: incremental.Value<T>,\n raw: unknown,\n extractor: AnnotationExtractor<T>,\n): Input<Annotation> {\n const annotation = extractor.fromValue(value)\n\n if (value.content) {\n switch (value.content.type) {\n case 'array':\n return new ArrayContentWrapper<T>(value.content, raw as unknown[], annotation, extractor)\n case 'object':\n return new ObjectContentWrapper<T>(\n value.content,\n raw as Record<string, unknown>,\n annotation,\n extractor,\n )\n case 'string':\n return new StringContentWrapper<T>(value.content, raw as string, annotation, extractor)\n default:\n // do nothing\n }\n }\n\n return wrap(raw, annotation)\n}\n\nfunction extractAnnotationForFromInput(\n transactions: TransactionLogEventWithEffects[],\n meta: EventMeta,\n): Annotation {\n if (meta) {\n // The next transaction is where it disappeared:\n return annotationForTransactionIndex(transactions, meta.transactionIndex + 1, meta.event)\n }\n\n // Fallback: if meta is null, the value existed initially and was changed/removed\n // by the first transaction in our range\n if (transactions.length > 0) {\n return annotationForTransactionIndex(transactions, 0)\n }\n\n return null\n}\nfunction extractAnnotationForToInput(\n transactions: TransactionLogEventWithEffects[],\n meta: EventMeta,\n): Annotation {\n if (meta) {\n return annotationForTransactionIndex(transactions, meta.transactionIndex, meta.event)\n }\n\n return null\n}\n\nfunction annotationForTransactionIndex(\n transactions: TransactionLogEventWithEffects[],\n idx: number,\n event?: DocumentGroupEvent,\n) {\n const tx = transactions[idx]\n if (!tx) return null\n\n return {\n event: event,\n timestamp: tx.timestamp,\n author: tx.author,\n }\n}\n\nexport function diffValue({\n transactions,\n fromValue,\n fromRaw,\n toValue,\n toRaw,\n}: {\n transactions: TransactionLogEventWithEffects[]\n fromValue: incremental.Value<EventMeta>\n fromRaw: Omit<SanityDocument, '_rev'>\n toValue: incremental.Value<EventMeta>\n toRaw: Omit<SanityDocument, '_rev'>\n}) {\n const fromInput = wrapValue<EventMeta>(fromValue, fromRaw, {\n fromValue(value) {\n return extractAnnotationForFromInput(transactions, value.endMeta)\n },\n fromMeta(meta) {\n return extractAnnotationForFromInput(transactions, meta)\n },\n })\n\n const toInput = wrapValue<EventMeta>(toValue, toRaw, {\n fromValue(value) {\n return extractAnnotationForToInput(transactions, value.startMeta)\n },\n fromMeta(meta) {\n return extractAnnotationForToInput(transactions, meta)\n },\n })\n return diffInput(fromInput, toInput)\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type Diff, diffInput} from '@sanity/diff'\nimport {type incremental} from 'mendoza'\n\nimport {type Annotation, type Chunk} from '../../../field/types'\nimport {wrapValue} from '../../events/diffValue'\nimport {type Timeline} from './Timeline'\n\n/**\n * @deprecated\n */\nexport type Meta = {chunk: Chunk; transactionIndex: number} | null\n\nfunction extractAnnotationForFromInput(\n timeline: Timeline,\n firstChunk: Chunk | null,\n meta: Meta,\n): Annotation {\n if (meta) {\n // The next transaction is where it disappeared:\n return annotationForTransactionIndex(timeline, meta.transactionIndex + 1, meta.chunk.index)\n } else if (firstChunk) {\n return annotationForTransactionIndex(timeline, firstChunk.start, firstChunk.index)\n }\n\n return null\n}\n\n// oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\nfunction extractAnnotationForToInput(timeline: Timeline, meta: Meta): Annotation {\n if (meta) {\n return annotationForTransactionIndex(timeline, meta.transactionIndex, meta.chunk.index)\n }\n\n return null\n}\n\n// oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\nfunction annotationForTransactionIndex(timeline: Timeline, idx: number, chunkIdx?: number) {\n const tx = timeline.transactionByIndex(idx)\n if (!tx) return null\n\n const chunk = timeline.chunkByTransactionIndex(idx, chunkIdx)\n if (!chunk) return null\n\n return {\n chunk,\n timestamp: tx.timestamp,\n author: tx.author,\n }\n}\n\n/**\n * @deprecated use the events api diff value with support for transactions instead.\n */\nexport function diffValue(\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n timeline: Timeline,\n firstChunk: Chunk | null,\n from: incremental.Value<Meta>,\n fromRaw: unknown,\n to: incremental.Value<Meta>,\n toRaw: unknown,\n): Diff<Annotation> {\n const fromInput = wrapValue<Meta>(from, fromRaw, {\n fromValue(value) {\n return extractAnnotationForFromInput(timeline, firstChunk, value.endMeta)\n },\n fromMeta(meta) {\n return extractAnnotationForFromInput(timeline, firstChunk, meta)\n },\n })\n\n const toInput = wrapValue<Meta>(to, toRaw, {\n fromValue(value) {\n return extractAnnotationForToInput(timeline, value.startMeta)\n },\n fromMeta(meta) {\n return extractAnnotationForToInput(timeline, meta)\n },\n })\n return diffInput(fromInput, toInput)\n}\n","export type Merger<T> = (left: T, right: T) => T | [T, T]\n\n/**\n * The two ended array supports pushing both at the beginning and\n * at the end while preserving indicies.\n */\nexport class TwoEndedArray<T extends {index: number}> {\n private _postive: T[] = []\n private _negative: T[] = []\n\n addToEnd(elem: T): void {\n elem.index = this._postive.length\n this._postive.push(elem)\n }\n\n addToBeginning(elem: T): void {\n // Prefer to place things at the positive side if possible.\n if (this.length == 0) {\n this.addToEnd(elem)\n return\n }\n\n elem.index = -(this._negative.length + 1)\n this._negative.push(elem)\n }\n\n mergeAtEnd(value: T, merger: Merger<T>): void {\n if (this.length === 0) {\n this.addToEnd(value)\n return\n }\n\n const idx = this.lastIdx\n const result = merger(this.get(idx), value)\n if (Array.isArray(result)) {\n this.set(idx, result[0])\n this.addToEnd(result[1])\n } else {\n this.set(idx, result)\n }\n }\n\n mergeAtBeginning(value: T, merger: Merger<T>): void {\n if (this.length === 0) {\n this.addToEnd(value)\n return\n }\n\n const idx = this.firstIdx\n const result = merger(value, this.get(idx))\n if (Array.isArray(result)) {\n this.set(idx, result[1])\n this.addToBeginning(result[0])\n } else {\n this.set(idx, result)\n }\n }\n\n removeFromEnd(): void {\n if (this._postive.length === 0) {\n this._negative.shift()\n } else {\n this._postive.pop()\n }\n }\n\n has(idx: number): boolean {\n if (idx >= 0) {\n return idx < this._postive.length\n }\n\n return -(idx + 1) < this._negative.length\n }\n\n get(idx: number): T {\n if (idx >= 0) {\n return this._postive[idx]\n }\n\n return this._negative[-(idx + 1)]\n }\n\n set(idx: number, value: T): void {\n if (idx >= 0) {\n value.index = idx\n this._postive[idx] = value\n } else {\n value.index = idx\n this._negative[-(idx + 1)] = value\n }\n }\n\n get lastIdx(): number {\n // Note: This also works correctly when _positive is empty (it returns -1)\n return this._postive.length - 1\n }\n\n get last(): T {\n return this.get(this.lastIdx)\n }\n\n get firstIdx(): number {\n // Note: This also works correctly when _negative is empty (it returns 0)\n return -this._negative.length\n }\n\n get first(): T {\n return this.get(this.firstIdx)\n }\n\n get length(): number {\n return this._postive.length + this._negative.length\n }\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type CombinedDocument} from './types'\n\nexport function getAttrs(doc: CombinedDocument): Record<string, unknown> | null {\n return doc.draft || doc.published\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type Diff} from '@sanity/diff'\nimport {type TransactionLogEventWithEffects} from '@sanity/types'\nimport {applyPatch, incremental} from 'mendoza'\n\nimport {type Annotation, type Chunk} from '../../../field/types'\nimport {chunkFromTransaction, mergeChunk} from './chunker'\nimport {diffValue, type Meta} from './diffValue'\nimport {type TraceEvent} from './replay'\nimport {TwoEndedArray} from './TwoEndedArray'\nimport {\n type CombinedDocument,\n type DocumentRemoteMutationVersionEvent,\n type Transaction,\n} from './types'\nimport {getAttrs} from './utils'\n\n/**\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta */\nexport type ParsedTimeRef = Chunk | 'loading' | 'invalid'\n\n/**\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta */\nexport interface TimelineOptions {\n publishedId: string\n enableTrace?: boolean\n}\n\n/**\n * Timeline maintains information about the history of a document:\n * Grouping raw translog entries into sensible groups, replaying and\n * reconstructing different versions and abstract other details.\n *\n * Note that this class by itself is not capable of _fetching_ information,\n * but will only organize and structure the incoming translog entries.\n *\n *\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta\n */\nexport class Timeline {\n reachedEarliestEntry = false\n\n publishedId: string\n draftId: string\n private _transactions = new TwoEndedArray<Transaction>()\n private _chunks = new TwoEndedArray<Chunk>()\n\n // These two properties are here to handle the case\n private _possiblePendingTransactions = new Map<\n string,\n {\n transaction: Transaction\n idx: number\n }\n >()\n private _recreateTransactionsFrom?: number\n private _trace?: TraceEvent[]\n\n constructor(opts: TimelineOptions) {\n this.publishedId = opts.publishedId\n this.draftId = `drafts.${opts.publishedId}`\n\n if (opts.enableTrace) {\n this._trace = []\n this._trace.push({\n type: 'initial',\n publishedId: opts.publishedId,\n })\n ;(window as any).__sanityTimelineTrace = this._trace\n }\n }\n\n get chunkCount(): number {\n return this._chunks.length\n }\n\n /** Maps over the chunk from newest to oldest. */\n mapChunks<T>(mapper: (chunk: Chunk, idx: number) => T): T[] {\n const result: T[] = []\n\n const firstIdx = this._chunks.firstIdx\n const lastIdx = this._chunks.lastIdx\n\n for (let idx = lastIdx; idx >= firstIdx; idx--) {\n result.push(mapper(this._chunks.get(idx), idx))\n }\n\n return result\n }\n\n reset(): void {\n this._transactions = new TwoEndedArray()\n this._chunks = new TwoEndedArray()\n this._possiblePendingTransactions = new Map()\n this._recreateTransactionsFrom = undefined\n this.reachedEarliestEntry = false\n }\n\n /**\n * Adds a remote mutation to the timeline. This methods assumes that the remote mutations\n * come in correct order for their respective version, but has no ordering requirements\n * across draft/published.\n *\n * Example: [D1, D2, P1] (where D1 and P1 were mutations done to the draft and published\n * version in the same transaction) is a valid input. [P1, D2, D1] is _not_ valid since\n * the mutation for the draft is out of order.\n */\n addRemoteMutation(entry: DocumentRemoteMutationVersionEvent): void {\n if (this._trace) this._trace.push({type: 'addRemoteMutation', event: entry})\n\n const pending = this._possiblePendingTransactions.get(entry.transactionId)\n\n const transaction: Transaction = pending\n ? pending.transaction\n : {\n index: 0,\n id: entry.transactionId,\n timestamp: entry.timestamp.toISOString(),\n author: entry.author,\n }\n\n if (entry.version === 'draft') {\n transaction.draftEffect = entry.effects as any\n } else {\n transaction.publishedEffect = entry.effects as any\n }\n\n if (pending) {\n this._possiblePendingTransactions.delete(entry.transactionId)\n this._invalidateTransactionFrom(pending.idx)\n } else {\n this._transactions.addToEnd(transaction)\n this._possiblePendingTransactions.set(entry.transactionId, {\n transaction,\n idx: this._transactions.lastIdx,\n })\n }\n }\n\n addTranslogEntry(event: TransactionLogEventWithEffects): void {\n if (this._trace) this._trace.push({type: 'addTranslogEntry', event})\n\n this._transactions.addToBeginning({\n index: 0,\n id: event.id,\n author: event.author,\n timestamp: event.timestamp,\n draftEffect: event.effects[this.draftId],\n publishedEffect: event.effects[this.publishedId],\n })\n }\n\n /** Mark that we've reached the earliest entry. */\n didReachEarliestEntry(): void {\n if (this._trace) this._trace.push({type: 'didReachEarliestEntry'})\n\n this.reachedEarliestEntry = true\n }\n\n /**\n * updateChunks synchronizes the chunks to match the current state\n * of the transactions array. After calling this method you need\n * to invalidate all Chunks.\n */\n updateChunks(): void {\n if (this._trace) this._trace.push({type: 'updateChunks'})\n\n this._removeInvalidatedChunks()\n this._addChunksFromTransactions()\n this._createInitialChunk()\n }\n\n private _removeInvalidatedChunks() {\n if (this._recreateTransactionsFrom) {\n while (this._chunks.length > 0) {\n const chunk = this._chunks.last\n if (this._recreateTransactionsFrom < chunk.end) {\n this._chunks.removeFromEnd()\n } else {\n break\n }\n }\n this._recreateTransactionsFrom = undefined\n }\n }\n\n private _addChunksFromTransactions() {\n const firstIdx = this._transactions.firstIdx\n const lastIdx = this._transactions.lastIdx\n\n // Add transactions at the end:\n const nextTransactionToChunk = this._chunks.length > 0 ? this._chunks.last.end : firstIdx\n for (let idx = nextTransactionToChunk; idx <= lastIdx; idx++) {\n const transaction = this._transactions.get(idx)\n this._chunks.mergeAtEnd(chunkFromTransaction(transaction), mergeChunk)\n }\n\n // Add transactions at the beginning:\n if (this._chunks.length == 0) return\n\n const firstTransactionChunked = this._chunks.first.start\n\n for (let idx = firstTransactionChunked - 1; idx >= firstIdx; idx--) {\n const transaction = this._transactions.get(idx)\n this._chunks.mergeAtBeginning(chunkFromTransaction(transaction), mergeChunk)\n }\n }\n\n private _invalidateTransactionFrom(idx: number) {\n if (this._recreateTransactionsFrom === undefined || idx < this._recreateTransactionsFrom) {\n this._recreateTransactionsFrom = idx\n }\n }\n\n private _createInitialChunk() {\n if (this.reachedEarliestEntry) {\n if (this._chunks.first?.type === 'initial') return\n\n const firstTx = this._transactions.first\n if (!firstTx) return\n const initialChunk = chunkFromTransaction(firstTx)\n initialChunk.type = 'initial'\n initialChunk.id = '@initial'\n initialChunk.end = initialChunk.start\n this._chunks.addToBeginning(initialChunk)\n }\n }\n\n /**\n * Resolves a time reference.\n *\n * Note that the chunk returned is only valid if the timeline stays constant.\n * Once the timeline is updated, you must re-parse all references.\n */\n parseTimeId(id: string): ParsedTimeRef {\n if (this._chunks.length === 0) {\n return this.reachedEarliestEntry ? 'invalid' : 'loading'\n }\n\n // NOTE:\n // This was refactored from\n // ```\n // const [timestampStr, chunkId] = id.split('/', 3)\n // ```\n // in order to avoid issues with `@microsoft/api-extractor`.\n const idSegments = id.split('/', 3)\n const timestampStr = idSegments.shift()\n const chunkId = idSegments.shift()\n const timestamp = Number(timestampStr)\n\n for (let idx = this._chunks.lastIdx; idx >= this._chunks.firstIdx; idx--) {\n const chunk = this._chunks.get(idx)\n if (chunk.id === chunkId) {\n return chunk\n }\n\n if (Date.parse(chunk.endTimestamp) + 60 * 60 * 1000 < timestamp) {\n // The chunk ended _before_ the timestamp we're asking for. This means that there\n // is no point in looking further and the chunk is invalid.\n\n // We add 1 hour to allow some slack since transactions are not guaranteed to be in order.\n return 'invalid'\n }\n }\n\n return this.reachedEarliestEntry ? 'invalid' : 'loading'\n }\n\n findLastPublishedBefore(chunk: Chunk | null): ParsedTimeRef {\n for (\n let chunkIdx = chunk ? chunk.index - 1 : this._chunks.lastIdx;\n chunkIdx >= this._chunks.firstIdx;\n chunkIdx--\n ) {\n const currentChunk = this._chunks.get(chunkIdx)\n if (currentChunk.type === 'publish' || currentChunk.type === 'initial') {\n return currentChunk\n }\n }\n\n if (!this.reachedEarliestEntry) return 'loading'\n\n return this._chunks.first\n }\n\n isLatestChunk(chunk: Chunk): boolean {\n return chunk === this._chunks.last\n }\n\n createTimeId(chunk: Chunk): string {\n return `${chunk.endTimestamp.valueOf()}/${chunk.id}`\n }\n\n lastChunk(): Chunk {\n return this._chunks.last\n }\n\n transactionByIndex(idx: number): Transaction | null {\n if (!this._transactions.has(idx)) return null\n return this._transactions.get(idx)\n }\n\n chunkByTransactionIndex(idx: number, startChunkIdx = 0): Chunk {\n let chunkIdx = startChunkIdx\n for (;;) {\n const chunk = this._chunks.get(chunkIdx)\n if (!chunk) throw new Error('transaction does not belong in any chunk')\n\n if (idx >= chunk.end) {\n chunkIdx++\n } else if (idx < chunk.start) {\n chunkIdx--\n } else {\n return chunk\n }\n }\n }\n\n replayBackwardsBetween(\n firstIdx: number,\n lastIdx: number,\n doc: CombinedDocument,\n ): CombinedDocument {\n let draft = doc.draft\n let published = doc.published\n\n for (let idx = lastIdx; idx >= firstIdx; idx--) {\n const transaction = this._transactions.get(idx)\n\n if (transaction.draftEffect) {\n draft = applyPatch(draft, transaction.draftEffect.revert)\n }\n\n if (transaction.publishedEffect) {\n published = applyPatch(published, transaction.publishedEffect.revert)\n }\n }\n\n return {draft, published}\n }\n\n replayBackwardsUntil(firstIdx: number, doc: CombinedDocument): CombinedDocument {\n return this.replayBackwardsBetween(firstIdx, this._transactions.lastIdx, doc)\n }\n\n calculateDiff(\n initialDoc: CombinedDocument,\n finalDoc: CombinedDocument,\n firstIdx: number,\n lastIdx: number,\n ): Diff<Annotation> {\n let draftValue = incremental.wrap<Meta>(initialDoc.draft, null)\n let publishedValue = incremental.wrap<Meta>(initialDoc.published, null)\n\n const initialValue = getValue(draftValue, publishedValue)\n const initialAttributes = getAttrs(initialDoc)\n let firstChunk: Chunk | null = null\n\n // Loop over all of the chunks:\n for (let chunkIdx = firstIdx; chunkIdx <= lastIdx; chunkIdx++) {\n const chunk = this._chunks.get(chunkIdx)\n if (!firstChunk) firstChunk = chunk\n\n for (let idx = chunk.start; idx < chunk.end; idx++) {\n const transaction = this._transactions.get(idx)\n\n const meta = {\n chunk,\n transactionIndex: idx,\n }\n\n const preDraftValue = draftValue\n const prePublishedValue = publishedValue\n\n if (transaction.draftEffect) {\n draftValue = incremental.applyPatch(draftValue, transaction.draftEffect.apply, meta)\n }\n\n if (transaction.publishedEffect) {\n publishedValue = incremental.applyPatch(\n publishedValue,\n transaction.publishedEffect.apply,\n meta,\n )\n }\n\n const didHaveDriaft = incremental.getType(preDraftValue) !== 'null'\n const haveDraft = incremental.getType(draftValue) !== 'null'\n const havePublished = incremental.getType(publishedValue) !== 'null'\n\n if (havePublished && !haveDraft) {\n publishedValue = incremental.rebaseValue(preDraftValue, publishedValue)\n }\n\n if (haveDraft && !didHaveDriaft) {\n draftValue = incremental.rebaseValue(prePublishedValue, draftValue)\n }\n }\n }\n\n const finalValue = incremental.getType(draftValue) === 'null' ? publishedValue : draftValue\n const finalAttributes = getAttrs(finalDoc)\n\n return diffValue(this, firstChunk, initialValue, initialAttributes, finalValue, finalAttributes)\n }\n}\n\nfunction getValue(draftValue: incremental.Value<Meta>, publishedValue: incremental.Value<Meta>) {\n return incremental.getType(draftValue) === 'null' ? publishedValue : draftValue\n}\n","import {ClientError, ServerError} from '@sanity/client'\nimport {\n type TransactionLogEventWithMutations,\n type TransactionLogEventWithEffects,\n} from '@sanity/types'\n\nimport {DEFAULT_STUDIO_CLIENT_HEADERS} from '../../studioClient'\n\ntype StreamResult =\n | (TransactionLogEventWithEffects & TransactionLogEventWithMutations)\n | {error: {description?: string; type: string}}\n\nexport async function getJsonStream(\n url: string,\n token: string | undefined,\n): Promise<ReadableStream<StreamResult>> {\n const options: RequestInit = token\n ? {headers: {...DEFAULT_STUDIO_CLIENT_HEADERS, Authorization: `Bearer ${token}`}}\n : {credentials: 'include', headers: DEFAULT_STUDIO_CLIENT_HEADERS}\n const response = await fetch(url, options)\n if (!response.ok) {\n throw await toHttpError(response, url)\n }\n return getStream(response)\n}\n\n/**\n * Builds the same error `@sanity/client` throws for a non-OK response, so callers (and the studio's\n * request-error handler, which only claims `HttpError`s) can treat translog failures like any other\n * API failure: `statusCode`, `response.headers` (e.g. `retry-after`) and the API's error message.\n */\nasync function toHttpError(response: Response, url: string): Promise<Error> {\n const text = await response.text()\n const headers = Object.fromEntries(response.headers.entries())\n let body: unknown = text\n if ((headers['content-type'] || '').includes('application/json')) {\n try {\n body = JSON.parse(text)\n } catch {\n // keep the raw text\n }\n }\n const res = {\n statusCode: response.status,\n statusMessage: response.statusText,\n headers,\n body,\n url,\n method: 'GET',\n }\n return response.status >= 500 ? new ServerError(res) : new ClientError(res)\n}\n\nfunction getStream(response: Response): ReadableStream<StreamResult> {\n const body = response.body\n if (!body) {\n throw new Error('Failed to read body from response')\n }\n\n let reader: ReadableStreamDefaultReader<Uint8Array>\n let cancelled = false\n\n return new ReadableStream<TransactionLogEventWithEffects & TransactionLogEventWithMutations>({\n start(controller): void | PromiseLike<void> {\n reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n\n reader\n .read()\n .then(function processResult(result): void | Promise<void> {\n if (result.done) {\n if (cancelled) {\n return\n }\n\n buffer = buffer.trim()\n if (buffer.length === 0) {\n controller.close()\n return\n }\n\n controller.enqueue(JSON.parse(buffer))\n controller.close()\n return\n }\n\n buffer += decoder.decode(result.value, {stream: true})\n const lines = buffer.split('\\n')\n\n for (let i = 0; i < lines.length - 1; ++i) {\n const line = lines[i].trim()\n if (line.length === 0) {\n continue\n }\n\n try {\n controller.enqueue(JSON.parse(line))\n } catch (err) {\n controller.error(err)\n cancelled = true\n void reader.cancel()\n return\n }\n }\n\n buffer = lines[lines.length - 1]\n\n return reader\n .read()\n .then(processResult)\n .catch((err) => controller.error(err))\n })\n .catch((err) => controller.error(err))\n },\n\n cancel(): void {\n cancelled = true\n void reader.cancel()\n },\n })\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type SanityDocument, type TransactionLogEventWithEffects} from '@sanity/types'\nimport {applyPatch} from 'mendoza'\n\nimport {type RemoteSnapshotVersionEvent} from '../../document/document-pair/checkoutPair'\nimport {type Timeline} from './Timeline'\nimport {type CombinedDocument, type DocumentRemoteMutationVersionEvent} from './types'\n\ntype VersionState = {\n id: string\n hasAttrs: boolean\n attrs: Record<string, unknown> | null\n rev: string | null\n events: Array<DocumentRemoteMutationVersionEvent>\n aligned: boolean\n}\n\nfunction emptyVersionState(id: string): VersionState {\n return {\n id,\n hasAttrs: false,\n attrs: null,\n rev: null,\n events: [],\n aligned: false,\n }\n}\n\nfunction align(history: TransactionLogEventWithEffects, state: VersionState): number {\n const idx = state.events.findIndex((evt) => history.id === evt.transactionId)\n if (idx >= 0) {\n // Return the next event as we don't want this to be included.\n return idx + 1\n }\n\n if (state.rev) {\n return state.rev === history.id ? 0 : -1\n }\n\n // At this point the document doesn't exist and we were not able to match\n // it up with a received mutation. This is a bit unfortunate as we don't\n // have a _reliably_ way of aligning it. For now we just always assume\n // that it's consistent.\n\n return 0\n}\n\nfunction startFromSnapshot(state: VersionState, doc: SanityDocument) {\n state.hasAttrs = true\n\n if (doc) {\n state.attrs = {...doc}\n if (typeof state.attrs._rev != 'string') throw new Error('snapshot has no _rev')\n state.rev = state.attrs._rev\n delete state.attrs._rev\n } else {\n state.attrs = null\n state.rev = null\n }\n\n state.events = []\n}\n\n/**\n * The timeline consists of data from (1) the history, (2) live draft mutations, and\n * (3) live published mutations. It's critical for us that the chain of transactions\n * is complete and without holes. The following class can be used as a layer in front\n * of Timeline to ensure this:\n *\n * - Invoke `appendRemoteSnapshotEvent` when there's an incoming remote mutation.\n * These mutations are buffered internally and _not_ passed to the timeline quite yet.\n *\n * - Once we've received snapshots for both draft and published, then `acceptsHistory`\n * becomes true and the caller can fetch a chunk of the translog. The flag\n * `earliestTransactionId` can be used to figure out where to fetch transactions from.\n *\n * - The caller invokes `prependHistoryEvent` for each of the events. These history events\n * are always pushed to the timeline and it will become available immediately.\n *\n * - Internally this class will then try to align the history event to the received\n * mutations and then dispatch to the timeline.\n *\n * - The aligner also maintains the latest revision for both the draft and the published version.\n *\n *\n */\nexport class Aligner {\n timeline: Timeline\n earliestTransactionId: string | null = null\n\n constructor(timeline: Timeline) {\n this.timeline = timeline\n this._states = {\n draft: emptyVersionState(timeline.draftId),\n published: emptyVersionState(timeline.publishedId),\n }\n }\n\n private _states: {\n draft: VersionState\n published: VersionState\n }\n\n appendRemoteSnapshotEvent(evt: RemoteSnapshotVersionEvent): void {\n if (evt.version === 'version') {\n return\n }\n\n const state = this._states[evt.version]\n\n if (evt.type === 'snapshot') {\n this._maybeInvalidateHistory()\n\n startFromSnapshot(state, evt.document)\n return\n }\n\n if (evt.type === 'remoteMutation') {\n if (state.aligned) {\n this._apply(state, evt)\n this.timeline.addRemoteMutation(evt)\n } else if (state.hasAttrs) {\n state.events.push(evt)\n } else {\n startFromSnapshot(state, evt.head)\n }\n }\n }\n\n prependHistoryEvent(evt: TransactionLogEventWithEffects): void {\n if (!this.acceptsHistory) throw new Error('cannot prepend history at this point')\n\n for (const state of Object.values(this._states)) {\n if (!state.aligned) {\n const idx = align(evt, state)\n\n if (idx >= 0) {\n this._alignAtIndex(state, idx)\n }\n }\n }\n\n this.timeline.addTranslogEntry(evt)\n this.earliestTransactionId = evt.id\n }\n\n didReachEarliestEntry(): void {\n for (const state of Object.values(this._states)) {\n if (!state.aligned) {\n if (state.attrs !== null) throw new Error('unable to find translog entry to align to')\n this._alignAtIndex(state, 0)\n }\n }\n this.timeline.didReachEarliestEntry()\n }\n\n get isAligned(): boolean {\n return Object.values(this._states).every((state) => state.aligned)\n }\n\n get acceptsHistory(): boolean {\n return this._isComplete\n }\n\n get currentDocument(): CombinedDocument {\n return {draft: this._states.draft.attrs, published: this._states.published.attrs}\n }\n\n private _alignAtIndex(state: VersionState, idx: number) {\n // These we must only apply locally since they are present in the fetched translog.\n for (const mutEvt of state.events.slice(0, idx)) {\n this._apply(state, mutEvt)\n }\n\n // ... while these must also be pushed to the timeline:\n for (const mutEvt of state.events.slice(idx)) {\n this._apply(state, mutEvt)\n this.timeline.addRemoteMutation(mutEvt)\n }\n\n state.events = []\n state.aligned = true\n }\n\n private get _isComplete(): boolean {\n return Object.values(this._states).every((state) => state.hasAttrs)\n }\n\n private _apply(state: VersionState, evt: DocumentRemoteMutationVersionEvent) {\n state.attrs = applyPatch(state.attrs, evt.effects.apply as any)\n state.rev = evt.transactionId\n }\n\n private _maybeInvalidateHistory() {\n if (this._isComplete) {\n for (const state of Object.values(this._states)) {\n state.aligned = false\n }\n this.earliestTransactionId = null\n this.timeline.reset()\n }\n }\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type Diff} from '@sanity/diff'\n\nimport {type Annotation, type Chunk} from '../../../field/types'\nimport {type Timeline} from './Timeline'\nimport {type CombinedDocument} from './types'\n\n/**\n * A reconstruction represents a single reconstruction of a\n */\nexport class Reconstruction {\n timeline: Timeline\n start: Chunk | null\n end: Chunk\n doc: CombinedDocument\n\n constructor(timeline: Timeline, doc: CombinedDocument, start: Chunk | null, end: Chunk) {\n this.timeline = timeline\n this.start = start\n this.end = end\n this.doc = doc\n }\n\n same(start: Chunk | null, end: Chunk): boolean {\n return this.start === start && this.end === end\n }\n\n private _startDocument?: CombinedDocument\n private _endDocument?: CombinedDocument\n private _diff?: Diff<Annotation>\n\n /** Returns the attributes as seen at the end of the range. */\n endAttributes(): Record<string, unknown> | null {\n return getAttrs(this.endDocument())\n }\n\n endDocument(): CombinedDocument {\n if (!this._endDocument) {\n this._endDocument = this.timeline.replayBackwardsUntil(this.end.end, this.doc)\n }\n\n return this._endDocument\n }\n\n /** Returns the attributes as seen at the end of the range. */\n startAttributes(): Record<string, unknown> | null {\n return getAttrs(this.startDocument())\n }\n\n startDocument(): CombinedDocument {\n if (!this.start) throw new Error('start required')\n\n if (!this._startDocument) {\n this._startDocument = this.timeline.replayBackwardsBetween(\n this.start.end,\n this.end.end - 1,\n this.endDocument(),\n )\n }\n\n return this._startDocument\n }\n\n diff(): Diff<Annotation> {\n if (!this._diff) {\n if (!this.start) throw new Error('start required')\n\n this._diff = this.timeline.calculateDiff(\n this.startDocument(),\n this.endDocument(),\n this.start.index + 1,\n this.end.index,\n )\n }\n\n return this._diff\n }\n}\n\nfunction getAttrs(doc: CombinedDocument) {\n return doc.draft || doc.published\n}\n","/* oxlint-disable no-deprecated -- this module implements the deprecated legacy document timeline */\nimport {type SanityClient} from '@sanity/client'\nimport {type Diff, type ObjectDiff} from '@sanity/diff'\n\nimport {type Annotation, type Chunk} from '../../../field/types'\nimport {type RemoteSnapshotVersionEvent} from '../../document/document-pair/checkoutPair'\nimport {getJsonStream} from '../../events/getJsonStream'\nimport {Aligner} from './Aligner'\nimport {Reconstruction} from './Reconstruction'\nimport {type ParsedTimeRef, type Timeline} from './Timeline'\n\nconst TRANSLOG_ENTRY_LIMIT = 50\n\n/**\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta */\nexport type TimelineControllerOptions = {\n timeline: Timeline\n client: SanityClient\n documentId: string\n documentType: string\n handler?: (err: Error | null, controller: TimelineController) => void\n}\n\n/**\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta */\nexport type SelectionState = 'inactive' | 'rev' | 'range' | 'loading' | 'invalid'\n\n/**\n * The controller is responsible for fetching information\n * about a document and maintaining a Timeline.\n *\n *\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @hidden\n * @beta\n */\nexport class TimelineController {\n timeline: Timeline\n client: SanityClient\n handler: TimelineControllerOptions['handler']\n\n version = 0\n\n /**\n * The selection state represents the different states of the current selection:\n * - inactive: No selection is active.\n * - rev: A selection is active for a single revision.\n * - range: A selection is active for a range and we have all the data needed to render it.\n * - loading: A selection is active, but we don't have the entries yet.\n * - invalid: The selection picked is invalid.\n */\n selectionState: SelectionState = 'inactive'\n\n constructor(options: TimelineControllerOptions) {\n this.timeline = options.timeline\n this.client = options.client\n this.handler = options.handler\n this._aligner = new Aligner(this.timeline)\n\n this.markChange()\n }\n\n private _aligner: Aligner\n\n private _fetchMore = false\n private _fetchAtLeast = 0\n private _isRunning = false\n private _isSuspended = false\n private _didErr = false\n\n private _since: string | null = null\n private _sinceTime: ParsedTimeRef | null = null\n private _rev: string | null = null\n private _revTime: ParsedTimeRef | null = null\n\n private _reconstruction?: Reconstruction\n\n setHandler(handler: TimelineControllerOptions['handler']): void {\n this.handler = handler\n }\n\n clearRange(): void {\n this.setRange(null, null)\n }\n\n setRange(since: string | null, rev: string | null): void {\n if (rev !== this._rev) this.setRevTime(rev)\n if (since !== this._since) this.setSinceTime(since)\n\n let _fetchAtLeast = 10\n\n if (this._sinceTime === 'loading' || this._revTime === 'loading' || !this._aligner.isAligned) {\n this.selectionState = 'loading'\n } else if (this._sinceTime === 'invalid' || this._revTime === 'invalid') {\n this.selectionState = 'invalid'\n } else if (this._sinceTime) {\n this.selectionState = 'range'\n\n const targetRev = this._revTime || this.timeline.lastChunk()\n\n if (this._sinceTime.index > targetRev.index) {\n this._revTime = 'invalid'\n this.selectionState = 'invalid'\n } else {\n this.setReconstruction(this._sinceTime, targetRev)\n }\n } else if (this._revTime) {\n this.selectionState = 'rev'\n this.setReconstruction(null, this._revTime)\n } else {\n this.selectionState = 'inactive'\n _fetchAtLeast = 0\n }\n\n this._fetchAtLeast = _fetchAtLeast\n\n this.start()\n }\n\n setLoadMore(flag: boolean): void {\n this._fetchMore = flag\n this.start()\n }\n\n get sinceTime(): Chunk | null {\n return this._sinceTime && typeof this._sinceTime === 'object' ? this._sinceTime : null\n }\n\n get revTime(): Chunk | null {\n return this._revTime && typeof this._revTime === 'object' ? this._revTime : null\n }\n\n get isLoading(): boolean {\n return this._isRunning\n }\n\n get realRevChunk(): Chunk {\n return this.revTime || this.timeline.lastChunk()\n }\n\n /** Returns true when there's an older revision we want to render. */\n onOlderRevision(): boolean {\n return Boolean(this._rev) && (this.selectionState === 'range' || this.selectionState === 'rev')\n }\n\n findRangeForNewRev(rev: Chunk): [string | null, string | null] {\n const revTimeId = this.timeline.isLatestChunk(rev) ? null : this.timeline.createTimeId(rev)\n\n if (!this._since) {\n return [null, revTimeId]\n }\n\n const sinceChunk = this.sinceTime\n if (sinceChunk && sinceChunk.index < rev.index) {\n return [this._since, revTimeId]\n }\n\n return ['@lastPublished', revTimeId]\n }\n\n findRangeForNewSince(since: Chunk): [string, string | null] {\n const revChunk = this.revTime\n\n // If the the `since` timestamp is earlier than the `rev`, then we can\n // accept it. Otherwise we'll move the current revision to the current draft.\n\n if (revChunk && since.index < revChunk.index) {\n return [this.timeline.createTimeId(since), this._rev]\n }\n\n return [this.timeline.createTimeId(since), null]\n }\n\n setRevTime(rev: string | null): void {\n this._rev = rev\n this._revTime = rev ? this.timeline.parseTimeId(rev) : null\n\n if (this._since === '@lastPublished') {\n // Make sure we invalidate it since this depends on the _rev.\n this._since = null\n this._sinceTime = null\n }\n }\n\n setSinceTime(since: string | null): void {\n if (since === '@lastPublished') {\n if (typeof this._revTime === 'string') {\n this._sinceTime = this._revTime\n } else {\n this._sinceTime = this.timeline.findLastPublishedBefore(this._revTime)\n }\n } else {\n this._sinceTime = since ? this.timeline.parseTimeId(since) : null\n }\n\n this._since = since\n }\n\n sinceAttributes(): Record<string, unknown> | null {\n return this._sinceTime && this._reconstruction ? this._reconstruction.startAttributes() : null\n }\n\n displayed(): Record<string, unknown> | null {\n return this._revTime && this._reconstruction ? this._reconstruction.endAttributes() : null\n }\n\n setReconstruction(since: Chunk | null, rev: Chunk): void {\n if (this._reconstruction && this._reconstruction.same(since, rev)) return\n this._reconstruction = new Reconstruction(\n this.timeline,\n this._aligner.currentDocument,\n since,\n rev,\n )\n }\n\n currentDiff(): Diff<Annotation> | null {\n return this._reconstruction ? this._reconstruction.diff() : null\n }\n\n currentObjectDiff(): ObjectDiff<Annotation> | null {\n const diff = this.currentDiff()\n if (diff) {\n if (diff.type === 'null') return null\n if (diff.type !== 'object') throw new Error(`ObjectDiff expected, got ${diff.type}`)\n }\n\n return diff as ObjectDiff<Annotation>\n }\n\n handleRemoteMutation(ev: RemoteSnapshotVersionEvent): void {\n this._aligner.appendRemoteSnapshotEvent(ev)\n this.markChange()\n\n // Make sure we fetch history as soon as possible.\n if (this._aligner.acceptsHistory) this.start()\n }\n\n start(): void {\n if (this._didErr) return\n\n if (!this._isRunning) {\n this._isRunning = true\n\n void this.tick().then(() => {\n this._isRunning = false\n })\n }\n }\n\n resume(): void {\n this._isSuspended = false\n }\n\n suspend(): void {\n this._isSuspended = true\n }\n\n private async tick() {\n const shouldFetchMore =\n this._aligner.acceptsHistory &&\n !this.timeline.reachedEarliestEntry &&\n (this.selectionState === 'loading' ||\n this._fetchMore ||\n this.timeline.chunkCount <= this._fetchAtLeast) &&\n !this._isSuspended\n\n if (!shouldFetchMore) {\n this._isRunning = false\n return\n }\n\n try {\n await this.fetchMoreTransactions()\n } catch (err) {\n this._didErr = true\n this.handler?.(err, this)\n return\n }\n\n await this.tick()\n }\n\n private async fetchMoreTransactions() {\n const publishedId = this.timeline.publishedId\n const draftId = this.timeline.draftId\n const clientConfig = this.client.config()\n const limit = TRANSLOG_ENTRY_LIMIT\n\n let queryParams = `tag=sanity.studio.structure.history&effectFormat=mendoza&excludeContent=true&excludeMutations=true&includeIdentifiedDocumentsOnly=true&reverse=true&limit=${limit}`\n let tid = this._aligner.earliestTransactionId\n if (tid) {\n queryParams += `&toTransaction=${tid}`\n }\n\n const transactionsUrl = this.client.getUrl(\n `/data/history/${clientConfig.dataset}/transactions/${publishedId},${draftId}?${queryParams}`,\n )\n const stream = await getJsonStream(transactionsUrl, clientConfig.token)\n const reader = stream.getReader()\n let count = 0\n\n for (;;) {\n // oxlint-disable-next-line no-await-in-loop\n const result = await reader.read()\n if (result.done) break\n\n if ('error' in result.value) {\n throw new Error(result.value.error.description || result.value.error.type)\n }\n\n count++\n\n if (result.value.id === tid) {\n // toTransaction is inclusive so we must ignore it when we fetch the next page\n continue\n }\n\n // For some reason, the aligner is now interested in a different set of entries.\n // This can happen if a new snapshot comes in as we're streaming the translog.\n // In this case it's safe to abort, and the run-loop will re-schedule it correctly.\n if (this._aligner.earliestTransactionId !== tid || !this._aligner.acceptsHistory) {\n return\n }\n\n this._aligner.prependHistoryEvent(result.value)\n tid = this._aligner.earliestTransactionId\n }\n\n // Same consistency checking here:\n if (this._aligner.earliestTransactionId !== tid || !this._aligner.acceptsHistory) {\n return\n }\n\n if (count < limit) {\n this._aligner.didReachEarliestEntry()\n }\n\n this.markChange()\n }\n\n private markChange() {\n this.timeline.updateChunks()\n\n this.setRevTime(this._rev)\n this.setSinceTime(this._rev)\n\n this.version++\n this.handler?.(null, this)\n }\n}\n","import {type Action, type SanityClient} from '@sanity/client'\nimport {type DocumentId, isDraftId, isVersionId} from '@sanity/id-utils'\nimport {\n isReference,\n type Reference,\n type SanityDocument,\n type TransactionLogEventWithMutations,\n} from '@sanity/types'\nimport {reduce as jsonReduce} from 'json-reduce'\nimport {from, type Observable} from 'rxjs'\nimport {map, mergeMap} from 'rxjs/operators'\n\nimport {isDev} from '../../environment'\nimport {getDraftId, getPublishedId, getVersionFromId, getIdPair} from '../../util/draftUtils'\nimport {isRecord} from '../../util/isRecord'\nimport {actionsApiClient} from '../document/document-pair/utils/actionsApiClient'\nimport {Timeline} from './history/Timeline'\nimport {TimelineController} from './history/TimelineController'\n\n/**\n * Represents a document revision identifier.\n * Can be either a specific revision string\n * or 'lastRevision' to get the most recent revision.\n *\n * @beta\n */\nexport type DocumentRevision = string | 'lastRevision'\n\n/**\n * @hidden\n * @beta */\nexport interface HistoryStore {\n getDocumentAtRevision: (\n documentId: string,\n revision: DocumentRevision,\n ) => Promise<SanityDocument | undefined>\n\n getHistory: (\n documentIds: string[],\n options?: {time?: string; revision?: string},\n ) => Promise<{documents: SanityDocument[]}>\n\n getTransactions: (documentIds: string[]) => Promise<TransactionLogEventWithMutations[]>\n\n restore: (\n id: string,\n targetId: string,\n rev: DocumentRevision,\n options?: RestoreOptions,\n ) => Observable<void>\n\n /**\n * @deprecated Use the events API instead. The legacy document timeline will be removed in the next major version.\n * @internal\n */\n getTimelineController: (options: {\n client: SanityClient\n documentId: string\n documentType: string\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n }) => TimelineController\n}\n\ninterface RestoreOptions {\n fromDeleted: boolean\n useServerDocumentActions?: boolean\n}\n\nconst documentRevisionCache: Record<string, Promise<SanityDocument | undefined> | undefined> =\n Object.create(null)\n\nconst getHistory = (\n client: SanityClient,\n documentIds: string[],\n options: {time?: string; revision?: string} = {},\n): Promise<{documents: SanityDocument[]}> => {\n const ids = Array.isArray(documentIds) ? documentIds : [documentIds]\n const {time, revision} = options\n\n if (time && revision) {\n throw new Error(`getHistory can't handle both time and revision parameters`)\n }\n\n const dataset = client.config().dataset\n let url = `/data/history/${dataset}/documents/${ids.join(',')}`\n\n if (revision) {\n url = `${url}?revision=${revision}`\n } else {\n const timestamp = time || new Date().toISOString()\n\n url = `${url}?time=${timestamp}`\n }\n\n return client.request({url})\n}\n\nconst getDocumentAtRevision = (\n client: SanityClient,\n documentId: string,\n revision: DocumentRevision,\n): Promise<SanityDocument | undefined> => {\n const publishedId = getPublishedId(documentId)\n const draftId = getDraftId(documentId)\n const versionId = isVersionId(documentId as DocumentId) ? documentId : undefined\n const idsToQuery = [publishedId, draftId, versionId].filter(Boolean) as DocumentId[]\n\n const isLastRevision = revision === 'lastRevision'\n\n if (!isLastRevision) {\n const cacheKey = `${documentId}@${revision}`\n const cached = documentRevisionCache[cacheKey]\n if (cached) {\n return cached\n }\n }\n\n const dataset = client.config().dataset\n const url = `/data/history/${dataset}/documents/${idsToQuery.join(',')}?${\n isLastRevision ? 'lastRevision=true' : `revision=${revision}`\n }`\n\n const entry = client\n .request<{documents?: SanityDocument[]}>({url, tag: 'history-revision'})\n .then((result) => {\n const documents = result.documents || []\n const published = documents.find((res) => res._id === publishedId)\n const draft = documents.find((res) => res._id === draftId)\n const version = versionId ? documents.find((res) => res._id === versionId) : undefined\n\n if (revision !== 'lastRevision') {\n if (version?._rev === revision) return version\n if (draft?._rev === revision) return draft\n if (published?._rev === revision) return published\n return undefined\n }\n return version || draft || published\n })\n\n if (!isLastRevision) {\n const cacheKey = `${documentId}@${revision}`\n documentRevisionCache[cacheKey] = entry\n }\n\n return entry\n}\n\nconst getTimelineController = ({\n client,\n documentId,\n documentType,\n}: {\n client: SanityClient\n documentId: string\n documentType: string\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n}): TimelineController => {\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n const timeline = new Timeline({\n enableTrace: isDev,\n publishedId: documentId,\n })\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n return new TimelineController({\n client,\n documentId,\n documentType,\n timeline,\n })\n}\n\nconst getTransactions = async (\n client: SanityClient,\n documentIds: string | string[],\n): Promise<TransactionLogEventWithMutations[]> => {\n const ids = Array.isArray(documentIds) ? documentIds : [documentIds]\n const dataset = client.config().dataset\n const query = {excludeContent: 'true', includeIdentifiedDocumentsOnly: 'true'}\n const url = `/data/history/${dataset}/transactions/${ids.join(',')}`\n const result = await client.request({url, query})\n const transactions = result\n .toString('utf8')\n .split('\\n')\n .filter(Boolean)\n .map((line: string) => JSON.parse(line))\n\n return transactions\n}\n\nconst getAllRefIds = (doc: SanityDocument): string[] =>\n jsonReduce(\n doc as any,\n (acc: any, node) => (isReference(node) && !acc.includes(node._ref) ? [...acc, node._ref] : acc),\n [],\n )\n\nfunction jsonMap(value: unknown, mapFn: any): any {\n if (Array.isArray(value)) {\n return mapFn(\n value.map((item) => jsonMap(item, mapFn)).filter((item) => typeof item !== 'undefined'),\n )\n }\n\n if (isRecord(value)) {\n return mapFn(\n Object.keys(value).reduce<Record<string, unknown>>((res, key) => {\n const mappedValue = jsonMap(value[key], mapFn)\n if (typeof mappedValue !== 'undefined') {\n res[key] = mappedValue\n }\n\n return res\n }, {}),\n )\n }\n\n return mapFn(value)\n}\n\nconst mapRefNodes = (doc: SanityDocument, mapFn: (node: Reference) => Reference | undefined) =>\n jsonMap(doc, (node: unknown) => (isReference(node) ? mapFn(node) : node))\n\n/** @internal */\nexport const removeMissingReferences = (\n doc: SanityDocument,\n existingIds: Record<string, boolean | undefined>,\n): SanityDocument =>\n mapRefNodes(doc, (refNode) => {\n const documentExists = existingIds[refNode._ref]\n return documentExists ? refNode : undefined\n })\n\nfunction restore(\n client: SanityClient,\n documentId: string,\n targetDocumentId: string,\n rev: DocumentRevision,\n options?: RestoreOptions,\n): Observable<void> {\n return from(getDocumentAtRevision(client, targetDocumentId, rev)).pipe(\n mergeMap((documentAtRevision) => {\n if (!documentAtRevision) {\n throw new Error(`Unable to find document with ID ${documentId} at revision ${rev}`)\n }\n if (rev !== 'lastRevision' && documentAtRevision?._rev !== rev) {\n throw new Error(\n `Restored revision ${documentAtRevision?._rev} does not match expected revision ${rev}`,\n )\n }\n\n const existingIdsQuery = getAllRefIds(documentAtRevision)\n .map((refId) => `\"${refId}\": defined(*[_id==\"${refId}\"]._id)`)\n .join(',')\n\n return client.observable\n .fetch<Record<string, boolean | undefined>>(`{${existingIdsQuery}}`)\n .pipe(map((existingIds) => removeMissingReferences(documentAtRevision, existingIds)))\n }),\n map((documentAtRevision) => {\n // Remove _updatedAt\n const {_updatedAt, ...document} = documentAtRevision\n return {...document, _id: targetDocumentId}\n }),\n mergeMap((restoredDraft) => {\n // `sanity.action.document.replaceDraft` requires `attributes._id` to be\n // prefixed with either `drafts.` or `versions.<bundleId>`. When it isn't\n // (e.g. restoring a live-edit document directly onto the published id),\n // fall back to the mutation API, matching the non-server-actions path.\n const canUseServerAction =\n isDraftId(targetDocumentId as DocumentId) || isVersionId(targetDocumentId as DocumentId)\n\n if (options?.useServerDocumentActions && canUseServerAction) {\n const replaceDraftAction: Action = {\n actionType: 'sanity.action.document.replaceDraft',\n publishedId: documentId,\n attributes: restoredDraft,\n }\n return actionsApiClient(\n client,\n // The pair derives from the *target* id: `documentId` is always the published group id\n // (its bundle segment is always undefined), while the target may be a version document\n // (release or variant scoped) whose actions require the versioned API client.\n getIdPair(documentId, {version: getVersionFromId(targetDocumentId)}),\n ).observable.action(\n options.fromDeleted\n ? [\n {\n actionType: 'sanity.action.document.create',\n publishedId: documentId,\n attributes: restoredDraft,\n // This will guard against a race where someone else restores a deleted document at the same time\n ifExists: 'fail',\n },\n replaceDraftAction,\n ]\n : replaceDraftAction,\n )\n }\n\n return client.observable.createOrReplace(restoredDraft, {visibility: 'async'})\n }),\n map(() => undefined),\n )\n}\n\n/** @internal */\nexport interface HistoryStoreOptions {\n client: SanityClient\n}\n\n/** @internal */\nexport function createHistoryStore({client}: HistoryStoreOptions): HistoryStore {\n return {\n getDocumentAtRevision: (documentId, revision) =>\n getDocumentAtRevision(client, documentId, revision),\n\n getHistory: (documentIds, options) => getHistory(client, documentIds, options),\n\n getTransactions: (documentIds) => getTransactions(client, documentIds),\n\n restore: (id, targetId, rev, options) => restore(client, id, targetId, rev, options),\n\n // oxlint-disable-next-line no-deprecated -- part of the deprecated legacy document timeline\n getTimelineController,\n }\n}\n","/**\n * Whether or not the current environment supports localStorage.\n * Checks that values can actually be set/removed, to trigger any privacy settings.\n *\n * @internal\n */\nexport const supportsLocalStorage = (() => {\n // Non-browser runtimes (Node.js 22+, Bun, Deno) may expose a built-in\n // `localStorage` global that either warns or behaves differently from the\n // browser implementation. Since this utility is only useful in real browsers,\n // bail out in non-browser environments — even if browser globals have been\n // mocked (e.g., jsdom in CLI commands/tests). `process.versions` is set by\n // all major server-side runtimes and is not faked by jsdom.\n // Note that `process.versions` may also be defined by frameworks.\n // E.g. Next.js/Turbopack polyfills it and sets it to an empty object\n if (\n typeof process !== 'undefined' &&\n typeof process.versions !== 'undefined' &&\n typeof process.versions.node !== 'undefined'\n ) {\n return false\n }\n\n const key = '__tmp_supports_local_storage'\n\n try {\n if (typeof localStorage === 'undefined') {\n return false\n }\n\n localStorage.setItem(key, '---')\n localStorage.removeItem(key)\n return true\n } catch {\n return false\n }\n})()\n","import {type KeyValueStoreValue} from '../types'\n\nexport function createMemoryStorage() {\n const DB = Object.create(null)\n return {\n getKey(key: string): KeyValueStoreValue | null {\n return DB[key] || null\n },\n setKey(key: string, value: KeyValueStoreValue) {\n DB[key] = value\n },\n }\n}\n","import {supportsLocalStorage} from '../../../util/supportsLocalStorage'\nimport {type KeyValueStoreValue} from '../types'\nimport {createMemoryStorage} from './memoryStorage'\n\nfunction tryParse(val: string) {\n try {\n return JSON.parse(val)\n } catch (err) {\n console.warn(`Failed to parse settings: ${err.message}`)\n return null\n }\n}\n\nfunction createLocalStoreStorage() {\n if (!supportsLocalStorage) {\n return createMemoryStorage()\n }\n\n function getKey(key: string): KeyValueStoreValue | null {\n const val = localStorage.getItem(key)\n\n return val === null ? null : tryParse(val)\n }\n\n const setKey = function (key: string, nextValue: KeyValueStoreValue) {\n // Can't stringify undefined, and nulls are what\n // `getItem` returns when key does not exist\n if (typeof nextValue === 'undefined' || nextValue === null) {\n localStorage.removeItem(key)\n } else {\n localStorage.setItem(key, JSON.stringify(nextValue))\n }\n }\n return {getKey, setKey}\n}\n\nexport const localStoreStorage = createLocalStoreStorage()\n","import {dequal as isEqual} from 'dequal/lite'\nimport {merge, of} from 'rxjs'\nimport {distinctUntilChanged, tap} from 'rxjs/operators'\n\nimport {localStoreStorage} from './storage/localStoreStorage'\nimport {type KeyValueStore, type KeyValueStoreValue} from './types'\n\n/**\n * Wraps a KeyValueStore and adds Stale-While-Revalidate (SWR) behavior to it\n */\nexport function withLocalStorageSWR(wrappedStore: KeyValueStore): KeyValueStore {\n function getKey(key: string) {\n return merge(\n of(localStoreStorage.getKey(key)),\n wrappedStore.getKey(key).pipe(\n tap((wrappedStoreValue) => {\n localStoreStorage.setKey(key, wrappedStoreValue)\n }),\n ),\n ).pipe(distinctUntilChanged(isEqual))\n }\n function setKey(key: string, nextValue: KeyValueStoreValue) {\n localStoreStorage.setKey(key, nextValue)\n return wrappedStore.setKey(key, nextValue)\n }\n return {\n getKey,\n setKey,\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport DataLoader from 'dataloader'\n\nimport {DEFAULT_STUDIO_CLIENT_OPTIONS} from '../../../studioClient'\nimport {type KeyValueStoreValue} from '../types'\nimport {type KeyValuePair} from './types'\n\n/** @internal */\nexport interface ServerStorageOptions {\n client: SanityClient\n}\n\nexport interface ServerStorage {\n getKey: (key: string) => Promise<KeyValueStoreValue | null>\n setKey: (key: string, nextValue: unknown) => Promise<KeyValueStoreValue>\n}\n\n/**\n * Backend uses the Sanity client to store and retrieve key-value pairs from the /users/me/keyvalue endpoint.\n * @internal\n */\nexport function createServerStorage({client: _client}: ServerStorageOptions): ServerStorage {\n const client = _client.withConfig(DEFAULT_STUDIO_CLIENT_OPTIONS)\n\n const keyValueLoader = new DataLoader<string, KeyValueStoreValue | null>(async (keys) => {\n const value = await client\n .request<KeyValuePair[]>({\n url: `/users/me/keyvalue/${keys.join(',')}`,\n })\n .catch((error) => {\n console.error('Error fetching data:', error)\n return Array(keys.length).fill(null)\n })\n\n // there are instances where the valeu might be null\n const keyValuePairs = (value || []).reduce(\n (acc, next) => {\n if (next?.key) {\n acc[next.key] = next.value\n }\n return acc\n },\n {} as Record<string, KeyValueStoreValue | null>,\n )\n\n return keys.map((key) => keyValuePairs[key] || null)\n })\n\n const getKey = (key: string) => {\n return keyValueLoader.load(key)\n }\n\n const setKey = (key: string, nextValue: unknown) => {\n return client\n .request<KeyValuePair[]>({\n method: 'PUT',\n url: `/users/me/keyvalue`,\n body: [{key, value: nextValue}],\n })\n .then(\n (response) => {\n const pair = response[0]\n keyValueLoader.clear(pair.key)\n keyValueLoader.prime(pair.key, pair.value)\n return pair.value\n },\n (error) => {\n console.error('Error setting data:', error)\n return null\n },\n )\n }\n\n return {\n getKey,\n setKey,\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {dequal as isEqual} from 'dequal/lite'\nimport {concat, type Observable, Subject} from 'rxjs'\nimport {distinctUntilChanged, filter, map} from 'rxjs/operators'\n\nimport {createServerStorage} from './storage/serverStorage'\nimport {type KeyValueStore, type KeyValueStoreValue} from './types'\n\nexport function createServerKeyValueStore({client}: {client: SanityClient}): KeyValueStore {\n const serverStorage = createServerStorage({client})\n\n const events$ = new Subject<{\n type: 'optimistic' | 'commit'\n key: string\n value: KeyValueStoreValue\n }>()\n\n function getKey(key: string) {\n return serverStorage.getKey(key)\n }\n\n function setKey(key: string, value: KeyValueStoreValue) {\n events$.next({type: 'optimistic', key, value})\n\n /*\n * The backend returns the result of the set operation, so we can just pass that along.\n * Most utils do not use it (they will take advantage of local state first) but it reflects the\n * backend function and could be useful for debugging.\n */\n return serverStorage.setKey(key, value).then((storedValue) => {\n events$.next({type: 'commit', key, value: storedValue})\n return storedValue\n })\n }\n\n return {\n getKey(key: string): Observable<KeyValueStoreValue | null> {\n return concat(\n getKey(key),\n events$.pipe(\n filter((event) => event.key === key),\n map((event) => event.value),\n distinctUntilChanged(isEqual),\n ),\n )\n },\n setKey,\n }\n}\n","import {type SanityClient} from '@sanity/client'\n\nimport {withLocalStorageSWR} from './localStorageSWR'\nimport {createServerKeyValueStore} from './serverKeyValueStore'\n\n/** @internal */\nexport function createKeyValueStore(options: {client: SanityClient}) {\n return withLocalStorageSWR(createServerKeyValueStore(options))\n}\n","import {type BifurClient} from '@sanity/bifur-client'\nimport {EMPTY, type Observable} from 'rxjs'\nimport {map, share} from 'rxjs/operators'\n\nimport {type PresenceLocation} from '../types'\nimport {type Transport, type TransportEvent, type TransportMessage} from './transport'\n\ntype BifurStateMessage = {\n type: 'state'\n i: string\n m: {\n sessionId: string\n locations: PresenceLocation[]\n }\n}\n\ntype BifurDisconnectMessage = {\n type: 'disconnect'\n i: string\n m: {session: string}\n}\n\ntype RollCallEvent = {\n type: 'rollCall'\n i: string\n session: string\n}\n\ntype IncomingBifurEvent<T> = RollCallEvent | BifurStateMessage | BifurDisconnectMessage\n\nconst handleIncomingMessage = (event: IncomingBifurEvent<Location[]>): TransportEvent => {\n if (event.type === 'rollCall') {\n return {\n type: 'rollCall',\n userId: event.i,\n sessionId: event.session,\n }\n }\n if (event.type === 'state') {\n const {sessionId, locations} = event.m\n return {\n type: 'state',\n userId: event.i,\n sessionId: sessionId,\n timestamp: new Date().toISOString(),\n locations,\n }\n }\n\n if (event.type === 'disconnect') {\n return {\n type: 'disconnect',\n userId: event.i,\n sessionId: event.m.session,\n timestamp: new Date().toISOString(),\n }\n }\n\n throw new Error(`Got unknown presence event: ${JSON.stringify(event)}`)\n}\n\nexport const createBifurTransport = (bifur: BifurClient, sessionId: string): Transport => {\n const incomingEvents$: Observable<TransportEvent> = bifur\n .listen<IncomingBifurEvent<Location[]>>('presence')\n .pipe(map(handleIncomingMessage))\n\n const dispatchMessage = (message: TransportMessage): Observable<undefined> => {\n if (message.type === 'rollCall') {\n return bifur.request('presence_rollcall', {session: sessionId})\n }\n\n if (message.type === 'state') {\n return bifur.request('presence_announce', {\n data: {locations: message.locations, sessionId},\n })\n }\n\n if (message.type === 'disconnect') {\n return bifur.request('presence_disconnect', {session: sessionId})\n }\n\n return EMPTY\n }\n\n return [incomingEvents$.pipe(share()), dispatchMessage]\n}\n","import sample from 'lodash-es/sample.js'\nimport {defer, timer} from 'rxjs'\nimport {map, mergeMapTo, shareReplay} from 'rxjs/operators'\n\nimport {type StateEvent} from './message-transports/transport'\n\nconst USERIDS = [\n 'pqSMwf6hH',\n 'pnLYqNfv5',\n 'priDVVmy8',\n 'p0NFOU0j8',\n 'pTDl2jw8d',\n 'pHMeQnTse',\n 'pDQYzJbyS',\n 'pZyoPHKUs',\n 'p4Tyi2Be5',\n 'pb9vii060',\n 'pE8yhOisw',\n 'p7Fd2C6Cj',\n 'p3exSgYCx',\n 'pbIQRYViC',\n 'p8GJaTEhN',\n 'p27ewL8aM',\n 'pYg97z75S',\n 'pdLr4quHv',\n 'pkJXiDgg6',\n 'pkl4UAKcA',\n\n // Included to ensure we handle the case when a user profile cannot\n // be fetched due to insufficient privileges or similar\n 'pNoExists',\n]\n\nconst PATHS = [\n ['nested', 'first'],\n ['nested', 'second'],\n [\n 'nestedArray',\n {_key: '565c867c8dac'},\n 'arrayNo1',\n {_key: 'a645548a8f01'},\n 'arrayNo1',\n {_key: '1685e372c40f'},\n 'fieldNo0',\n ],\n ['nestedArray', {_key: '565c867c8dac'}, 'fieldNo0'],\n ['nestedArray', {_key: '565c867c8dac'}, 'arrayNo19', {_key: 'a02e7a93e2a2'}, 'fieldNo0'],\n ['nestedArray', {_key: '565c867c8dac'}, 'arrayNo19', {_key: 'a02e7a93e2a2'}, 'fieldNo19'],\n ['address', 'country'],\n ['address', 'street'],\n ['customInputWithDefaultPresence', 'row3', 'cell3'],\n]\n\nexport const mock$ = defer(() => timer(0, 10000)).pipe(\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n mergeMapTo(USERIDS),\n map((id, n): StateEvent => ({\n type: 'state',\n userId: id,\n sessionId: id + n,\n timestamp: new Date().toISOString(),\n locations: [\n {\n type: 'document',\n documentId: 'presence-debug',\n lastActiveAt: new Date().toISOString(),\n path: sample(PATHS),\n },\n ] as any,\n })),\n shareReplay(),\n)\n","import {type BifurClient} from '@sanity/bifur-client'\nimport {type User} from '@sanity/types'\nimport {dequal as isEqual} from 'dequal/lite'\nimport flatten from 'lodash-es/flatten.js'\nimport groupBy from 'lodash-es/groupBy.js'\nimport omit from 'lodash-es/omit.js'\nimport uniq from 'lodash-es/uniq.js'\nimport {nanoid} from 'nanoid'\nimport {\n BehaviorSubject,\n combineLatest,\n defer,\n EMPTY,\n from,\n fromEvent,\n merge,\n NEVER,\n type Observable,\n timer,\n} from 'rxjs'\nimport {\n auditTime,\n distinctUntilChanged,\n filter,\n map,\n mergeMapTo,\n scan,\n share,\n shareReplay,\n switchMap,\n switchMapTo,\n takeUntil,\n tap,\n withLatestFrom,\n} from 'rxjs/operators'\n\nimport {documentIdEquals} from '../../util/draftUtils'\nimport {type ConnectionStatusStore} from '../connection-status/connection-status-store'\nimport {debugParams$} from '../debugParams/debugParams'\nimport {type UserStore} from '../user/userStore'\nimport {createBifurTransport} from './message-transports/bifurTransport'\nimport {\n type DisconnectEvent,\n type RollCallEvent,\n type StateEvent,\n type TransportEvent,\n} from './message-transports/transport'\nimport {mock$} from './mock-events'\nimport {\n type DocumentPresence,\n type GlobalPresence,\n type PresenceLocation,\n type Session,\n type UserSessionPair,\n} from './types'\n\n/**\n * @hidden\n * @beta */\nexport interface PresenceStore {\n /**\n * @internal\n */\n documentPresence: (\n documentId: string,\n options?: {excludeVersions?: boolean},\n ) => Observable<DocumentPresence[]>\n\n /**\n * @internal\n */\n globalPresence$: Observable<GlobalPresence[]>\n\n /**\n * @internal\n */\n reportLocations: (locations: PresenceLocation[]) => Observable<void>\n\n /**\n * @internal\n */\n setLocation: (nextLocation: PresenceLocation[]) => void\n\n /**\n * @internal\n */\n debugPresenceParam$: Observable<string[]>\n}\n\nconst KEY = 'presence_session_id'\nconst generate = () => nanoid(16)\n\n// We're keeping the session id in sessionStorage as it will survive page reloads.\n// todo:\n// There's a potential issue with window.open(...) here as it inherits the top level session storage and thus will\n// re-use session ids:\n// > Opening a page in a new tab or window creates a new session with the value of the top-level browsing context,\n// which differs from how session cookies work.\n// More at https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage\n// This is _probably_ a quite marginal case and not going to be much of a issue in practice\nfunction getSessionId() {\n try {\n return window.sessionStorage.getItem(KEY)\n } catch {\n // We don't want to fail hard if session storage can't be accessed for some reason\n }\n return null\n}\n\nfunction setSessionId(id: string) {\n try {\n window.sessionStorage.setItem(KEY, id)\n } catch {\n // We don't want to fail hard if session storage can't be accessed for some reason\n }\n return id\n}\n\n/** @internal */\nexport const SESSION_ID = getSessionId() || setSessionId(generate())\n\n/** @internal */\nexport function createPresenceStore(context: {\n bifur: BifurClient\n connectionStatusStore: ConnectionStatusStore\n userStore: UserStore\n}): PresenceStore {\n const {bifur, connectionStatusStore, userStore} = context\n\n const [presenceEvents$, sendMessage] = createBifurTransport(bifur, SESSION_ID)\n\n const currentLocation$ = new BehaviorSubject<PresenceLocation[]>([])\n const locationChange$ = currentLocation$.pipe(distinctUntilChanged())\n\n // export\n const setLocation = (nextLocation: PresenceLocation[]) => {\n currentLocation$.next(nextLocation)\n }\n\n // export\n const reportLocations = (locations: PresenceLocation[]) =>\n sendMessage({type: 'state', locations: locations})\n\n const requestRollCall = () => sendMessage({type: 'rollCall'})\n\n const rollCallRequests$ = presenceEvents$.pipe(\n filter((event: TransportEvent): event is RollCallEvent => event.type === 'rollCall'),\n // do not respond to my own rollcall requests\n filter((event: RollCallEvent) => event.sessionId !== SESSION_ID),\n )\n\n const REPORT_MIN_INTERVAL = 30000\n\n // Interval to report my own location at\n const reportLocationInterval$ = timer(0, REPORT_MIN_INTERVAL)\n\n const reportLocation$ = defer(() => merge(locationChange$, rollCallRequests$)).pipe(\n switchMap(() => reportLocationInterval$),\n withLatestFrom(currentLocation$),\n map(([, locations]) => locations),\n auditTime(200),\n switchMap((locations) => reportLocations(locations)),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n mergeMapTo(EMPTY),\n share(),\n )\n\n // This represents my rollcall request to other clients\n // Note: We are requesting a rollcall whenever we (re)connect\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const myRollCall$ = defer(() => requestRollCall()).pipe(mergeMapTo(EMPTY))\n\n const connectionChange$ = connectionStatusStore.connectionStatus$.pipe(\n map((status) => status.type),\n filter((statusType) => statusType === 'connected' || statusType === 'error'),\n distinctUntilChanged(),\n )\n\n // export\n const debugPresenceParam$ = debugParams$.pipe(\n map((args) => args.find((arg) => arg.startsWith('presence='))),\n map(\n (arg) =>\n arg\n ?.split('presence=')[1]\n .split(',')\n .map((r) => r.trim()) || [],\n ),\n )\n\n const useMock$ = debugPresenceParam$.pipe(\n filter((args) => args.includes('fake_others')),\n tap(() => {\n // oxlint-disable-next-line no-console\n console.log(\n 'Faking other users present in the studio. They will hang out in the document with _type: \"presence\" and _id: \"presence-debug\"',\n )\n }),\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n switchMapTo(mock$),\n )\n\n const debugIntrospect$ = debugPresenceParam$.pipe(map((args) => args.includes('show_own')))\n\n const syncEvent$ = merge(myRollCall$, presenceEvents$).pipe(\n filter(\n (event: TransportEvent): event is StateEvent | DisconnectEvent =>\n event.type === 'state' || event.type === 'disconnect',\n ),\n )\n\n const stateEventToSession = (stateEvent: StateEvent): Session => {\n return {\n lastActiveAt: stateEvent.timestamp,\n locations: stateEvent.locations,\n sessionId: stateEvent.sessionId,\n userId: stateEvent.userId,\n }\n }\n\n const states$: Observable<{[sessionId: string]: Session}> = merge(syncEvent$, useMock$).pipe(\n scan(\n (keyed, event: StateEvent | DisconnectEvent): {[sessionId: string]: Session} =>\n event.type === 'disconnect'\n ? omit(keyed, event.sessionId)\n : {...keyed, [event.sessionId]: stateEventToSession(event)},\n {},\n ),\n )\n\n const allSessions$: Observable<UserSessionPair[]> = connectionChange$.pipe(\n switchMap((status) => (status === 'connected' ? merge(states$, reportLocation$) : NEVER)),\n map((keyedSessions) => Object.values(keyedSessions)),\n switchMap((sessions) => {\n const userIds = uniq(sessions.map((sess) => sess.userId))\n return from(userStore.getUsers(userIds)).pipe(\n map((users) =>\n sessions\n .map((session) => ({\n user: users.find((res) => res.id === session.userId),\n session: session,\n }))\n // If we failed to find a user profile for a session, remove it\n .filter(userSessionPairHasUser),\n ),\n )\n }),\n takeUntil(\n fromEvent(window, 'beforeunload').pipe(switchMap(() => sendMessage({type: 'disconnect'}))),\n ),\n shareReplay({refCount: true, bufferSize: 1}),\n )\n\n function userSessionPairHasUser(pair: Partial<UserSessionPair>): pair is UserSessionPair {\n return Boolean(pair.user && pair.session)\n }\n\n // export\n const globalPresence$: Observable<GlobalPresence[]> = allSessions$.pipe(\n map((sessions): {user: User; sessions: Session[]}[] => {\n const grouped = groupBy(\n sessions.map((s) => s.session),\n (e) => e.userId,\n )\n\n return Object.keys(grouped).map((userId): {user: User; sessions: Session[]} => ({\n user: sessions.find((s) => s.user.id === userId)?.user as User,\n sessions: grouped[userId],\n }))\n }),\n withLatestFrom(debugIntrospect$),\n map(([userAndSessions, debugIntrospect]) =>\n userAndSessions.filter(\n (userAndSession) =>\n debugIntrospect || !userAndSession.sessions.some((sess) => sess.sessionId === SESSION_ID),\n ),\n ),\n map((userAndSessions) =>\n userAndSessions.map((userAndSession) => ({\n user: userAndSession.user,\n status: 'online',\n lastActiveAt: userAndSession.sessions.sort((a, b) =>\n b.lastActiveAt.localeCompare(a.lastActiveAt),\n )[0]?.lastActiveAt,\n locations: flatten(\n (userAndSession.sessions || []).map((session) => session.locations || []),\n )\n .map((location) => ({\n type: location.type,\n documentId: location.documentId,\n path: location.path,\n lastActiveAt: location.lastActiveAt,\n }))\n .reduce((prev, curr) => prev.concat(curr), [] as PresenceLocation[]),\n })),\n ),\n )\n\n // Create a single shared observable for all documents\n const allDocumentsPresence$ = combineLatest([allSessions$, debugIntrospect$]).pipe(\n map(([userAndSessions, debugIntrospect]) =>\n userAndSessions\n .flatMap((userAndSession) =>\n (userAndSession.session.locations || []).map((location) => ({\n documentId: location.documentId,\n presence: {\n user: userAndSession.user,\n lastActiveAt: userAndSession.session.lastActiveAt,\n path: location.path || [],\n sessionId: userAndSession.session.sessionId,\n selection: location?.selection,\n },\n })),\n )\n .filter((item) => debugIntrospect || item.presence.sessionId !== SESSION_ID),\n ),\n shareReplay(1),\n )\n\n /**\n * Returns document presence for the given documennt id\n * Presence are returned for all versions of the document\n */\n const documentPresence = (\n documentId: string,\n options?: {excludeVersions?: boolean},\n ): Observable<DocumentPresence[]> => {\n return allDocumentsPresence$.pipe(\n map((allPresence) =>\n allPresence\n .filter((item) =>\n options?.excludeVersions\n ? item.documentId === documentId\n : documentIdEquals(item.documentId, documentId),\n )\n .map((item) => ({\n ...item.presence,\n //documentId: getPublishedId(item.documentId),\n documentId: item.documentId,\n })),\n ),\n // Only emit if the presence has changed for this document id\n distinctUntilChanged((prev, curr) => isEqual(prev, curr)),\n )\n }\n\n return {setLocation, reportLocations, debugPresenceParam$, globalPresence$, documentPresence}\n}\n","import {type SanityClient} from '@sanity/client'\nimport {\n catchError,\n distinctUntilChanged,\n map,\n type Observable,\n of,\n repeat,\n ReplaySubject,\n scan,\n share,\n shareReplay,\n timer,\n} from 'rxjs'\n\nimport {memoize} from '../document/utils/createMemoizer'\nimport {createMemoKey, getClientCredentialSegments} from '../document/utils/memoKey'\nimport {type ProjectData, type ProjectGrants, type ProjectStore} from './types'\n\nconst REFETCH_INTERVAL = 5 * 60 * 1000 // 5 minutes\n\n// Memo key for the per-client request observables below. Must include the\n// credential, not just project/dataset — these poll `/projects` on a captured\n// client, so a stale-token entry would keep 401ing after a re-login (see\n// getClientCredentialSegments). The old entry goes idle when its last\n// subscriber leaves, but the memoizer never evicts, so its key and token string\n// are retained for the life of the page. Token stays in-memory (never logged).\nfunction projectRequestKey(client: SanityClient): string {\n return createMemoKey(getClientCredentialSegments(client))\n}\n\n/**\n * This value will be cached for 5 minutes, after that internal the cache will be refreshed.\n * If you need to be 100% sure the organizationId is up to date, you can call the `/projects/${projectId}` endpoint directly.\n */\nconst getProjectOrg = memoize((client: SanityClient) => {\n return client.observable\n .request<ProjectData>({\n url: `/projects/${client.config().projectId}`,\n tag: 'get-project-org',\n query: {\n includeMembers: 'false',\n includeFeatures: 'false',\n includeOrganization: 'true',\n },\n })\n .pipe(\n catchError(() => {\n return of(null)\n }),\n repeat({delay: REFETCH_INTERVAL}),\n // A transient refetch failure emits `null`. Retain the last known\n // project data so a failed refetch does not clobber a previously-good\n // organization id (which would strip org_id from telemetry events\n // flushed during the refetch window). See SAPP-3824.\n scan<ProjectData | null, ProjectData | null>((lastKnown, next) => next ?? lastKnown, null),\n distinctUntilChanged(),\n share({\n connector: () => new ReplaySubject(1),\n resetOnComplete: true,\n // delay unsubscriptions a little to keep the observable active\n // during React effect setup and teardown due to rapidly changing deps\n resetOnRefCountZero: () => timer(1000),\n }),\n )\n}, projectRequestKey)\n\nconst getOrganizationId = memoize(\n (client: SanityClient) => getProjectOrg(client).pipe(map((res) => res?.organizationId ?? null)),\n projectRequestKey,\n)\n\nconst getOrganizationData = memoize(\n (client: SanityClient) => getProjectOrg(client).pipe(map((res) => res?.organization ?? null)),\n projectRequestKey,\n)\n\n/**\n * Fetches the project grants for the current user, shared and replayed so all\n * permission checks reuse a single request. Memoized so callers outside the\n * project store (e.g. the schema/manifest upload gate) hit the same cached\n * observable instead of issuing a duplicate `/grants` request.\n *\n * Keyed by project/dataset **and credential** (see `projectRequestKey`),\n * matching the other memoized requests in this module, so a client for a\n * different project/dataset — or a new post-re-auth token — never reuses\n * another's grants.\n *\n * @internal\n */\nexport const getProjectGrants = memoize(\n (client: SanityClient): Observable<ProjectGrants> =>\n client.observable\n .request<ProjectGrants>({\n url: `/projects/${client.config().projectId}/grants`,\n tag: 'get-grants',\n })\n .pipe(shareReplay(1)),\n projectRequestKey,\n)\n\n/** @internal */\nexport function createProjectStore(context: {client: SanityClient}): ProjectStore {\n const {client} = context\n const projectId = client.config().projectId\n const versionedClient = client.withConfig({apiVersion: '2021-12-15'})\n\n function get(): Observable<ProjectData> {\n return versionedClient.observable.request({\n url: `/projects/${projectId}`,\n tag: 'get-project',\n })\n }\n\n function getDatasets() {\n return versionedClient.observable.request({\n url: `/projects/${projectId}/datasets`,\n tag: 'get-datasets',\n })\n }\n\n const projectOrgData$ = getProjectOrg(versionedClient)\n\n return {\n get,\n getDatasets,\n getGrants: () => getProjectGrants(versionedClient),\n getProjectName: () => projectOrgData$.pipe(map((res) => res?.displayName ?? null)),\n getOrganizationData: () => projectOrgData$.pipe(map((res) => res?.organization ?? null)),\n getOrganizationId: () => projectOrgData$.pipe(map((res) => res?.organizationId ?? null)),\n }\n}\n","import {type Observable} from 'rxjs'\n\n/**\n * @internal\n */\nexport type BaseStudioRenderingContext<\n Name extends string = string,\n Metadata = Record<PropertyKey, never>,\n> = {\n name: Name\n metadata: Metadata\n}\n\n/**\n * @internal\n */\nexport type DefaultRenderingContext = BaseStudioRenderingContext<'default'>\n\n/**\n * @internal\n */\nexport type CoreUiRenderingContext = BaseStudioRenderingContext<\n 'coreUi',\n {\n environment: string\n }\n>\n\n/**\n * @internal\n */\nexport type StudioRenderingContext = DefaultRenderingContext | CoreUiRenderingContext\n\n/**\n * @internal\n */\nexport const capabilities = ['globalUserMenu', 'globalWorkspaceControl', 'comlink'] as const\n\n/**\n * @internal\n */\nexport type Capability = (typeof capabilities)[number]\n\n/**\n * @internal\n */\nexport type CapabilityRecord = Partial<Record<Capability, boolean>>\n\n/**\n * @internal\n */\nexport type RenderingContextStore = {\n renderingContext: Observable<StudioRenderingContext>\n capabilities: Observable<CapabilityRecord>\n /**\n * The rendering context the store resolved when it was created — the value `renderingContext`\n * replays — for reading during render, where nothing may subscribe. `undefined` only while the\n * context is unresolved, which the store's own synchronous pipeline never is.\n */\n getRenderingContext: () => StudioRenderingContext | undefined\n /**\n * The capabilities of that rendering context — the value `capabilities` replays — for reading\n * during render, on the same terms as `getRenderingContext`.\n */\n getCapabilities: () => CapabilityRecord | undefined\n}\n\n/**\n * Check whether the provided value satisfies the `CoreUiRenderingContext` type.\n *\n * @internal\n */\nexport function isCoreUiRenderingContext(\n maybeCoreUiRenderingContext: unknown,\n): maybeCoreUiRenderingContext is CoreUiRenderingContext {\n return (\n typeof maybeCoreUiRenderingContext === 'object' &&\n maybeCoreUiRenderingContext !== null &&\n 'name' in maybeCoreUiRenderingContext &&\n maybeCoreUiRenderingContext.name === 'coreUi' &&\n 'metadata' in maybeCoreUiRenderingContext &&\n typeof maybeCoreUiRenderingContext.metadata === 'object' &&\n maybeCoreUiRenderingContext.metadata !== null &&\n 'environment' in maybeCoreUiRenderingContext.metadata &&\n typeof maybeCoreUiRenderingContext.metadata.environment === 'string'\n )\n}\n","import {\n catchError,\n distinctUntilChanged,\n map,\n of,\n type OperatorFunction,\n pipe,\n switchMap,\n} from 'rxjs'\n\nimport {isCoreUiRenderingContext, type StudioRenderingContext} from './types'\n\n// Core UI Rendering Context is provided via the URL query string, and remains static the entire\n// duration Studio is rendered inside the Core UI iframe.\n//\n// However, the URL query string is liable to be lost during Studio's lifecycle (for example, when\n// the user navigates to a different tool). Therefore, the URL query string is captured as soon as\n// this code is evaluated, and later referenced when a consumer subscribes to the store.\nconst INITIAL_URL_SEARCH = typeof location === 'object' ? location.search : ''\n\nconst CORE_UI_MODE_NAME = 'core-ui'\nconst CORE_UI_CONTEXT_SEARCH_PARAM = '_context'\n\n/**\n * @internal\n */\nexport function coreUiRenderingContext(\n urlSearch: string = INITIAL_URL_SEARCH,\n): OperatorFunction<StudioRenderingContext | undefined, StudioRenderingContext | undefined> {\n return pipe(\n switchMap((renderingContext) => {\n if (renderingContext) {\n return of(renderingContext)\n }\n\n return of(urlSearch).pipe(\n distinctUntilChanged(),\n map((search) => new URLSearchParams(search).get(CORE_UI_CONTEXT_SEARCH_PARAM)),\n map((serializedContext) => {\n if (serializedContext === null) {\n return undefined\n }\n\n const {mode, env} = JSON.parse(serializedContext)\n\n const coreUirenderingContext = {\n name: mode === CORE_UI_MODE_NAME ? 'coreUi' : undefined,\n metadata: {\n environment: env,\n },\n }\n\n if (isCoreUiRenderingContext(coreUirenderingContext)) {\n return coreUirenderingContext\n }\n\n return undefined\n }),\n catchError((error) => {\n console.warn('Error parsing rendering context:', error)\n return of(undefined)\n }),\n )\n }),\n )\n}\n","import {map, type OperatorFunction} from 'rxjs'\n\nimport {type DefaultRenderingContext, type StudioRenderingContext} from './types'\n\nconst DEFAULT_RENDERING_CONTEXT: DefaultRenderingContext = {\n name: 'default',\n metadata: {},\n}\n\n/**\n * @internal\n */\nexport function defaultRenderingContext(): OperatorFunction<\n StudioRenderingContext | undefined,\n StudioRenderingContext\n> {\n return map((renderingContext) => renderingContext ?? DEFAULT_RENDERING_CONTEXT)\n}\n","import {map, type OperatorFunction} from 'rxjs'\n\nimport {type CapabilityRecord, type StudioRenderingContext} from './types'\n\nconst capabilitiesByRenderingContext: Record<StudioRenderingContext['name'], CapabilityRecord> = {\n coreUi: {\n globalUserMenu: true,\n globalWorkspaceControl: true,\n comlink: true,\n },\n default: {},\n}\n\n/**\n * @internal\n */\nexport function listCapabilities(): OperatorFunction<StudioRenderingContext, CapabilityRecord> {\n return map((renderingContext) => capabilitiesByRenderingContext[renderingContext.name])\n}\n","import {of, shareReplay} from 'rxjs'\n\nimport {coreUiRenderingContext} from './coreUiRenderingContext'\nimport {defaultRenderingContext} from './defaultRenderingContext'\nimport {listCapabilities} from './listCapabilities'\nimport {\n type CapabilityRecord,\n type RenderingContextStore,\n type StudioRenderingContext,\n} from './types'\n\n/**\n * Rendering Context Store provides information about where Studio is being rendered, and which\n * capabilities are provided by the rendering context.\n *\n * This can be used to adapt parts of the Studio UI that are provided by the rendering context,\n * such as the global user menu.\n *\n * @param urlSearch - The URL query string to resolve the rendering context from; defaults to the\n * one captured when the studio booted.\n *\n * @internal\n */\nexport function createRenderingContextStore(urlSearch?: string): RenderingContextStore {\n const renderingContext = of(undefined).pipe(\n coreUiRenderingContext(urlSearch),\n defaultRenderingContext(),\n shareReplay(1),\n )\n\n const capabilities = renderingContext.pipe(listCapabilities(), shareReplay(1))\n\n // The context is static for the lifetime of the page and the pipeline resolves it synchronously\n // (the source completes right away), so connect both streams once here and keep the results:\n // consumers read them during render, where nothing may subscribe.\n let resolvedRenderingContext: StudioRenderingContext | undefined\n renderingContext.subscribe((value) => {\n resolvedRenderingContext = value\n })\n let resolvedCapabilities: CapabilityRecord | undefined\n capabilities.subscribe((value) => {\n resolvedCapabilities = value\n })\n\n return {\n renderingContext,\n capabilities,\n getRenderingContext: () => resolvedRenderingContext,\n getCapabilities: () => resolvedCapabilities,\n }\n}\n","interface MultiKeyWeakMapNode {\n type: 'multi-key-weak-map-node'\n value: unknown\n next: WeakMap<object, MultiKeyWeakMapNode>\n}\n\nexport interface MultiKeyWeakMap {\n get<T>(keys: object[]): T | undefined\n get(keys: object[]): unknown\n\n set(keys: object[], value: unknown): void\n}\n\nexport function createMultiKeyWeakMap(): MultiKeyWeakMap {\n const rootMap = new WeakMap<object, MultiKeyWeakMapNode>()\n const idCache = new WeakMap<object, string>()\n\n function randomId() {\n return Array.from({length: 10})\n .map(() =>\n Math.floor(Math.random() * 255)\n .toString(16)\n .padStart(2, '0'),\n )\n .join('')\n }\n\n function assignId(key: object) {\n const cachedId = idCache.get(key)\n if (cachedId) return cachedId\n const id = randomId()\n idCache.set(key, id)\n return id\n }\n\n function arrangeKeys(keys: object[]) {\n return Array.from(new Set(keys))\n .map((key) => [assignId(key), key] as const)\n .sort(([a], [b]) => a.localeCompare(b, 'en'))\n .map(([, key]) => key)\n }\n\n function getDeep(keys: object[], map: WeakMap<object, MultiKeyWeakMapNode>): unknown {\n if (!keys.length) return undefined\n const [firstKey, ...restOfKeys] = keys\n const node = map.get(firstKey)\n\n if (!node) return undefined\n if (!restOfKeys.length) return node.value\n return getDeep(restOfKeys, node.next)\n }\n\n function setDeep(\n keys: object[],\n map: WeakMap<object, MultiKeyWeakMapNode>,\n value: unknown,\n ): void {\n if (!keys.length) return\n\n const [firstKey, ...restOfKeys] = keys\n const node = map.get(firstKey) || {\n type: 'multi-key-weak-map-node',\n value: undefined,\n next: new WeakMap(),\n }\n map.set(firstKey, node)\n\n if (!restOfKeys.length) {\n node.value = value\n return\n }\n\n setDeep(restOfKeys, node.next, value)\n }\n\n function get<T>(keys: object[]): T | undefined\n function get(keys: object[]) {\n return getDeep(arrangeKeys(keys), rootMap)\n }\n\n function set(keys: object[], value: unknown) {\n setDeep(arrangeKeys(keys), rootMap, value)\n }\n\n return {get, set}\n}\n","import {type ReactNode, useContext, useState} from 'react'\nimport {ResourceCacheContext} from 'sanity/_singletons'\n\nimport {createMultiKeyWeakMap, type MultiKeyWeakMap} from './createMultiKeyWeakMap'\n\n/** @internal */\nexport interface ResourceCache {\n get<T = unknown>(options: {namespace: string; dependencies: (object | null)[]}): T | undefined\n set(options: {namespace: string; dependencies: (object | null)[]; value: unknown}): void\n}\n\n/** @internal */\nexport interface ResourceCacheProviderProps {\n children: ReactNode\n}\n\n/** @internal */\nexport function ResourceCacheProvider({children}: ResourceCacheProviderProps) {\n const [resourceCache] = useState((): ResourceCache => {\n const namespaces = new Map<string, MultiKeyWeakMap>()\n\n // this is used to replace the `null` values in any `dependencies` so that\n // they can be used in the `MultiKeyWeakMap` which doesn't accept null\n const nullReplacer = {}\n // this is used to replace `[]` dependencies to maintain the\n // same referential integrity in the weak map lookup\n const emptyDependenciesReplacer = [nullReplacer]\n\n const removeNullDependencies = (dependencies: (object | null)[]) =>\n dependencies.length\n ? dependencies.map((dep) => (dep === null ? nullReplacer : dep))\n : emptyDependenciesReplacer\n\n return {\n get: ({namespace, dependencies}) => {\n const dependenciesWithoutNull = removeNullDependencies(dependencies)\n const namespaceMap = namespaces.get(namespace)\n return namespaceMap?.get(dependenciesWithoutNull)\n },\n\n set: ({namespace, dependencies, value}) => {\n const namespaceMap = namespaces.get(namespace) || createMultiKeyWeakMap()\n const dependenciesWithoutNull = removeNullDependencies(dependencies)\n namespaces.set(namespace, namespaceMap)\n namespaceMap.set(dependenciesWithoutNull, value)\n },\n }\n })\n\n return (\n <ResourceCacheContext.Provider value={resourceCache}>{children}</ResourceCacheContext.Provider>\n )\n}\n\n/** @internal */\nexport function useResourceCache(): ResourceCache {\n const cache = useContext(ResourceCacheContext)\n if (!cache) throw new Error('Could not find `cache` context')\n return cache\n}\n","import {type SanityClient} from '@sanity/client'\nimport {type CurrentUser, type User} from '@sanity/types'\nimport DataLoader from 'dataloader'\nimport raf from 'raf'\n\nimport {isRecord} from '../../util/isRecord'\n\n/** @internal */\nexport interface UserStoreOptions {\n client: SanityClient\n currentUser: CurrentUser | null\n}\n\nconst INTERNAL_USER_IDS: User[] = [\n {\n id: '<system>',\n displayName: 'Sanity',\n imageUrl: 'https://public.sanity.io/logos/favicon-192.png',\n },\n]\n\n/**\n * @hidden\n * @beta */\nexport interface UserStore {\n getUser(userId: string): Promise<User | null>\n getUsers(userIds: string[]): Promise<User[]>\n}\n\n/**\n * Given a `client` and a `currentUser` creates a datastore that handles\n * fetching, batch fetching, and caching users.\n *\n * @internal\n */\nexport function createUserStore({client: _client, currentUser}: UserStoreOptions): UserStore {\n const client = _client.withConfig({apiVersion: '2021-06-07'})\n\n const userLoader = new DataLoader<string, User | null>(\n async (userIds) => {\n const value = await client.request<(User | null)[]>({\n url: `/users/${userIds.join(',')}`,\n tag: 'users.get',\n })\n const response = Array.isArray(value) ? value : [value]\n const users = response.reduce(\n (acc, next) => {\n if (next?.id) {\n acc[next.id] = next\n }\n return acc\n },\n {} as Record<string, User | null>,\n )\n return userIds.map((id) => users[id] || null)\n },\n {\n batchScheduleFn: (cb) => raf(cb),\n /**\n * User IDs are generally 9 bytes long, but external user IDs may be longer.\n * In order to keep the HTTP header size below ~8KB, we limit the batch size.\n * ~4kB for user IDs in paths should allow for plenty of headers, if need be.\n */\n maxBatchSize: 400,\n },\n )\n\n const userFromCurrentUser: User | null = currentUser && {\n id: currentUser.id,\n displayName: currentUser.name,\n imageUrl: currentUser.profileImage,\n sanityUserId: currentUser.sanityUserId ?? undefined,\n }\n\n userLoader.prime('me', userFromCurrentUser)\n\n if (userFromCurrentUser?.id) {\n userLoader.prime(userFromCurrentUser.id, userFromCurrentUser)\n }\n\n INTERNAL_USER_IDS.forEach((user) => userLoader.prime(user.id, user))\n\n return {\n getUser: async (userId) => {\n if (!userId) return Promise.resolve(null)\n\n try {\n return await userLoader.load(userId)\n } catch (err) {\n /**\n * 403 Forbidden responses indicate that the current user doesn't have read access to project members.\n * In these instances, we don't throw and resolve `null` instead.\n * Components consuming this (such as `<UserAvatar>`) shouldn't render anything in these cases.\n */\n if (err.statusCode === 403) {\n return Promise.resolve(null)\n }\n // Throw all other errors\n throw err\n }\n },\n getUsers: async (userIds) => {\n const results = await userLoader.loadMany(userIds)\n /**\n * Unlike `load()`, DataLoader's `loadMany()` will always resolve even if it contains `Error` instances.\n * Here, we remove all Errors (or more specifically, only include records with valid IDs).\n */\n return results.filter(\n (result): result is User => isRecord(result) && typeof result.id === 'string',\n )\n },\n }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {useTelemetry} from '@sanity/telemetry/react'\nimport {useToast} from '@sanity/ui/toast'\nimport {useCallback, useEffect, useMemo} from 'react'\nimport {useSyncObservable} from 'react-rx'\n\nimport {useClient} from '../hooks/useClient'\nimport {useSchema} from '../hooks/useSchema'\nimport {useTemplates} from '../hooks/useTemplates'\nimport {useTranslation} from '../i18n/hooks/useTranslation'\nimport {\n createDocumentPreviewStore,\n type DocumentPreviewStore,\n} from '../preview/documentPreviewStore'\nimport {useStudioErrorHandler} from '../studio/requestErrors/useStudioErrorHandler'\nimport {useSource} from '../studio/source'\nimport {useWorkspace} from '../studio/workspace'\nimport {DEFAULT_STUDIO_CLIENT_OPTIONS} from '../studioClient'\nimport {createComlinkStore} from './comlink/createComlinkStore'\nimport {type ComlinkStore} from './comlink/types'\nimport {\n type ConnectionStatusStore,\n createConnectionStatusStore,\n} from './connection-status/connection-status-store'\nimport {DocumentDesynced} from './document/__telemetry__/documentOutOfSyncEvents.telemetry'\nimport {DocumentPairLoadingMeasured} from './document/__telemetry__/documentPairLoading.telemetry'\nimport {DocumentRebaseOccurred} from './document/__telemetry__/documentRebase.telemetry'\nimport {HighListenerLatencyOccurred} from './document/__telemetry__/listenerLatency.telemetry'\nimport {MutationPerformanceMeasured} from './document/__telemetry__/mutationPerformance.telemetry'\nimport {createDocumentStore, type DocumentStore} from './document/document-store'\nimport {\n type DocumentPairLoadedEvent,\n type DocumentRebaseTelemetryEvent,\n type LatencyReportEvent,\n type MutationPerformanceEvent,\n} from './document/getPairListener'\nimport {type OutOfSyncError} from './document/utils/sequentializeListenerEvents'\nimport {createGrantsStore} from './grants/grantsStore'\nimport {type GrantsStore} from './grants/types'\nimport {createHistoryStore, type HistoryStore} from './history/createHistoryStore'\nimport {createKeyValueStore} from './key-value/keyValueStore'\nimport {type KeyValueStore} from './key-value/types'\nimport {createPresenceStore, type PresenceStore} from './presence/presence-store'\nimport {createProjectStore} from './project/projectStore'\nimport {type ProjectStore} from './project/types'\nimport {createRenderingContextStore} from './renderingContext/createRenderingContextStore'\nimport {type CapabilityRecord, type RenderingContextStore} from './renderingContext/types'\nimport {useResourceCache} from './ResourceCacheProvider'\nimport {createUserStore, type UserStore} from './user/userStore'\n\n/**\n * Latencies below this value will not be logged\n */\nconst EMPTY_CAPABILITIES: CapabilityRecord = {}\n\nconst IGNORE_LATENCY_BELOW_MS = 1000\n\n/** Minimum time between slow commit toast notifications */\nconst SLOW_COMMIT_TOAST_COOLDOWN_MS = 30_000\nconst slowCommitCooldown = {lastToastAt: 0}\n\n/**\n * @hidden\n * @beta */\nexport function useUserStore(): UserStore {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const {getClient, currentUser} = useSource()\n const resourceCache = useResourceCache()\n const client = getClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n\n return useMemo(() => {\n const userStore =\n resourceCache.get<UserStore>({\n namespace: 'userStore',\n dependencies: [client, currentUser],\n }) || createUserStore({client, currentUser})\n\n resourceCache.set({\n namespace: 'userStore',\n dependencies: [client, currentUser],\n value: userStore,\n })\n\n return userStore\n }, [client, currentUser, resourceCache])\n}\n\n/**\n * @hidden\n * @beta */\nexport function useGrantsStore(): GrantsStore {\n // `currentUser` is read from the source directly (instead of via `useCurrentUser` from\n // `./user/hooks`) to avoid a circular import: `./user/hooks` imports `useUserStore` from here.\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const {getClient, currentUser} = useSource()\n const client = getClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n const resourceCache = useResourceCache()\n const errorHandler = useStudioErrorHandler()\n\n return useMemo(() => {\n const grantsStore =\n resourceCache.get<GrantsStore>({\n namespace: 'grantsStore',\n dependencies: [client, currentUser, errorHandler],\n }) || createGrantsStore({client, userId: currentUser?.id || null, errorHandler})\n\n resourceCache.set({\n namespace: 'grantsStore',\n dependencies: [client, currentUser, errorHandler],\n value: grantsStore,\n })\n\n return grantsStore\n }, [client, currentUser, errorHandler, resourceCache])\n}\n\n/**\n * @hidden\n * @beta */\nexport function useHistoryStore(): HistoryStore {\n const client = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n const resourceCache = useResourceCache()\n\n return useMemo(() => {\n const historyStore =\n resourceCache.get<HistoryStore>({\n namespace: 'historyStore',\n dependencies: [client],\n }) || createHistoryStore({client})\n\n resourceCache.set({\n namespace: 'historyStore',\n dependencies: [client],\n value: historyStore,\n })\n\n return historyStore\n }, [client, resourceCache])\n}\n\n/**\n * @hidden\n * @beta */\nexport function useDocumentPreviewStore(): DocumentPreviewStore {\n const client = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n const resourceCache = useResourceCache()\n\n return useMemo(() => {\n const documentPreviewStore =\n resourceCache.get<DocumentPreviewStore>({\n namespace: 'documentPreviewStore',\n dependencies: [client],\n }) || createDocumentPreviewStore({client})\n\n resourceCache.set({\n namespace: 'documentPreviewStore',\n dependencies: [client],\n value: documentPreviewStore,\n })\n\n return documentPreviewStore\n }, [client, resourceCache])\n}\n\n/**\n * @hidden\n * @beta */\nexport function useDocumentStore(): DocumentStore {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const {getClient, i18n, currentUser} = useSource()\n const schema = useSchema()\n const templates = useTemplates()\n const resourceCache = useResourceCache()\n const historyStore = useHistoryStore()\n const documentPreviewStore = useDocumentPreviewStore()\n const workspace = useWorkspace()\n const telemetry = useTelemetry()\n const toast = useToast()\n const {t} = useTranslation()\n const errorHandler = useStudioErrorHandler()\n\n const handleSyncErrorRecovery = useCallback(\n (error: OutOfSyncError) => {\n telemetry.log(DocumentDesynced, {errorName: error.name})\n },\n [telemetry],\n )\n\n const handleReportLatency = useCallback(\n (event: LatencyReportEvent) => {\n if (event.latencyMs > IGNORE_LATENCY_BELOW_MS) {\n telemetry.log(HighListenerLatencyOccurred, {\n latency: event.latencyMs,\n shard: event.shard,\n transactionId: event.transactionId,\n })\n }\n },\n [telemetry],\n )\n\n const handleSlowCommit = useCallback(() => {\n const now = Date.now()\n if (now - slowCommitCooldown.lastToastAt < SLOW_COMMIT_TOAST_COOLDOWN_MS) return\n slowCommitCooldown.lastToastAt = now\n toast.push({\n title: t('document-store.slow-commit.title'),\n description: t('document-store.slow-commit.description'),\n status: 'warning',\n })\n }, [toast, t])\n\n const handleDocumentPairLoaded = useCallback(\n (event: DocumentPairLoadedEvent) => {\n telemetry.log(DocumentPairLoadingMeasured, {\n durationMs: event.durationMs,\n fromCache: event.fromCache,\n hasPublished: event.hasPublished,\n hasDraft: event.hasDraft,\n hasVersion: event.hasVersion,\n })\n },\n [telemetry],\n )\n\n const handleReportMutationPerformance = useCallback(\n (event: MutationPerformanceEvent) => {\n telemetry.log(MutationPerformanceMeasured, event)\n },\n [telemetry],\n )\n\n const handleDocumentRebase = useCallback(\n (event: DocumentRebaseTelemetryEvent) => {\n telemetry.log(DocumentRebaseOccurred, event)\n },\n [telemetry],\n )\n\n return useMemo(() => {\n const documentStore =\n resourceCache.get<DocumentStore>({\n namespace: 'documentStore',\n dependencies: [\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n errorHandler,\n ],\n }) ||\n createDocumentStore({\n getClient,\n documentPreviewStore,\n historyStore,\n initialValueTemplates: templates,\n schema,\n i18n,\n currentUser,\n extraOptions: {\n onReportLatency: handleReportLatency,\n onSyncErrorRecovery: handleSyncErrorRecovery,\n onSlowCommit: handleSlowCommit,\n onDocumentPairLoaded: handleDocumentPairLoaded,\n onReportMutationPerformance: handleReportMutationPerformance,\n onDocumentRebase: handleDocumentRebase,\n snapshotFetchErrorHandler: errorHandler,\n },\n })\n\n resourceCache.set({\n namespace: 'documentStore',\n dependencies: [\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n errorHandler,\n ],\n value: documentStore,\n })\n\n return documentStore\n }, [\n resourceCache,\n getClient,\n documentPreviewStore,\n historyStore,\n schema,\n i18n,\n workspace,\n currentUser,\n templates,\n handleReportLatency,\n handleSyncErrorRecovery,\n handleSlowCommit,\n handleDocumentPairLoaded,\n handleReportMutationPerformance,\n handleDocumentRebase,\n errorHandler,\n ])\n}\n\n/** @internal */\nexport function useConnectionStatusStore(): ConnectionStatusStore {\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n const {bifur} = useSource().__internal\n const resourceCache = useResourceCache()\n\n return useMemo(() => {\n const connectionStatusStore =\n resourceCache.get<ConnectionStatusStore>({\n namespace: 'connectionStatusStore',\n dependencies: [bifur],\n }) || createConnectionStatusStore({bifur})\n\n resourceCache.set({\n namespace: 'connectionStatusStore',\n dependencies: [bifur],\n value: connectionStatusStore,\n })\n\n return connectionStatusStore\n }, [bifur, resourceCache])\n}\n\n/**\n * @hidden\n * @beta */\nexport function usePresenceStore(): PresenceStore {\n const {\n __internal: {bifur},\n // oxlint-disable-next-line no-deprecated -- will fix in follow up PR\n } = useSource()\n const resourceCache = useResourceCache()\n const userStore = useUserStore()\n const connectionStatusStore = useConnectionStatusStore()\n\n return useMemo(() => {\n const presenceStore =\n resourceCache.get<PresenceStore>({\n namespace: 'presenceStore',\n dependencies: [bifur, connectionStatusStore, userStore],\n }) || createPresenceStore({bifur, connectionStatusStore, userStore})\n\n resourceCache.set({\n namespace: 'presenceStore',\n dependencies: [bifur, connectionStatusStore, userStore],\n value: presenceStore,\n })\n\n return presenceStore\n }, [bifur, connectionStatusStore, resourceCache, userStore])\n}\n\n/**\n * @hidden\n * @beta */\nexport function useProjectStore(): ProjectStore {\n const client = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n const resourceCache = useResourceCache()\n\n return useMemo(() => {\n const projectStore =\n resourceCache.get<ProjectStore>({\n namespace: 'projectStore',\n dependencies: [client],\n }) || createProjectStore({client})\n\n resourceCache.set({\n namespace: 'projectStore',\n dependencies: [client],\n value: projectStore,\n })\n\n return projectStore\n }, [client, resourceCache])\n}\n\n/**\n * Module-level cache for KeyValueStore instances, keyed by project identity.\n * Uses a simple Map with string keys since the ResourceCache's WeakMap\n * doesn't support primitive-based cache keys.\n */\nconst keyValueStoreCache = new Map<string, KeyValueStore>()\n\n/**\n * Generates a cache key for KeyValueStore based on project identity.\n * The /users/me/keyvalue endpoint is project-scoped, so we only need\n * projectId and apiHost (not dataset) to identify unique stores.\n */\nfunction getKeyValueStoreCacheKey(client: SanityClient): string {\n const config = client.config()\n return `${config.projectId}:${config.apiHost || 'default'}`\n}\n\n/**\n * Returns a KeyValueStore instance for storing user preferences.\n *\n * The store is cached by project identity (projectId + apiHost) rather than\n * workspace, because the /users/me/keyvalue endpoint is project-scoped -\n * user preferences are shared across all datasets within a project.\n *\n * @internal\n */\nexport function useKeyValueStore(): KeyValueStore {\n const client = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS)\n\n return useMemo(() => {\n const cacheKey = getKeyValueStoreCacheKey(client)\n const cached = keyValueStoreCache.get(cacheKey)\n if (cached) return cached\n\n const keyValueStore = createKeyValueStore({client})\n keyValueStoreCache.set(cacheKey, keyValueStore)\n return keyValueStore\n }, [client])\n}\n\n/** @internal */\nexport function useRenderingContextStore(): RenderingContextStore {\n const resourceCache = useResourceCache()\n\n return useMemo(() => {\n const renderingContextStore =\n resourceCache.get<RenderingContextStore>({\n dependencies: [],\n namespace: 'RenderingContextStore',\n }) || createRenderingContextStore()\n\n resourceCache.set({\n dependencies: [],\n namespace: 'RenderingContextStore',\n value: renderingContextStore,\n })\n\n return renderingContextStore\n }, [resourceCache])\n}\n\n/** @internal */\nexport function useComlinkStore(): ComlinkStore {\n const resourceCache = useResourceCache()\n const renderingContext = useRenderingContextStore()\n // Kept synchronous: the comlink node is created when `capabilities.comlink`\n // is true, so a deferred snapshot would delay comlink initialization.\n // Capabilities emit once at boot; there is nothing to gain from deferring\n // them. The store has already resolved them, so the comlink store is created\n // for the actual capabilities right away instead of once for `{}` and again\n // after the first emission.\n const capabilities = useSyncObservable(\n renderingContext.capabilities,\n () => renderingContext.getCapabilities() ?? EMPTY_CAPABILITIES,\n )\n\n const comlinkStore = useMemo(() => {\n const store =\n resourceCache.get<ComlinkStore>({\n dependencies: [capabilities],\n namespace: 'ComlinkStore',\n }) || createComlinkStore({capabilities})\n\n resourceCache.set({\n dependencies: [capabilities],\n namespace: 'ComlinkStore',\n value: store,\n })\n\n return store\n }, [capabilities, resourceCache])\n\n // The store is created during render, which React may abandon; the node is\n // only started once a consumer commits. Starting is idempotent, so every\n // consumer may ask for it.\n useEffect(() => {\n comlinkStore.start()\n }, [comlinkStore])\n\n return comlinkStore\n}\n"],"x_google_ignoreList":[103],"mappings":"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"}