sanity 3.72.1 → 3.72.2-use-live-content-api.9

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 (48) hide show
  1. package/lib/_chunks-cjs/LiveQueries.js +236 -163
  2. package/lib/_chunks-cjs/LiveQueries.js.map +1 -1
  3. package/lib/_chunks-cjs/PresentationToolGrantsCheck.js +3 -7
  4. package/lib/_chunks-cjs/PresentationToolGrantsCheck.js.map +1 -1
  5. package/lib/_chunks-cjs/buildAction.js +3 -0
  6. package/lib/_chunks-cjs/buildAction.js.map +1 -1
  7. package/lib/_chunks-cjs/presentation.js +3 -4
  8. package/lib/_chunks-cjs/presentation.js.map +1 -1
  9. package/lib/_chunks-cjs/version.js +1 -1
  10. package/lib/_chunks-es/LiveQueries.mjs +235 -162
  11. package/lib/_chunks-es/LiveQueries.mjs.map +1 -1
  12. package/lib/_chunks-es/PresentationToolGrantsCheck.mjs +2 -4
  13. package/lib/_chunks-es/PresentationToolGrantsCheck.mjs.map +1 -1
  14. package/lib/_chunks-es/presentation.mjs +3 -3
  15. package/lib/_chunks-es/presentation.mjs.map +1 -1
  16. package/lib/_chunks-es/version.mjs +1 -1
  17. package/lib/_internal/cli/threads/validateDocuments.js +1 -1
  18. package/lib/_internal/cli/threads/validateDocuments.js.map +1 -1
  19. package/lib/_legacy/LiveQueries.esm.js +235 -162
  20. package/lib/_legacy/LiveQueries.esm.js.map +1 -1
  21. package/lib/_legacy/PresentationToolGrantsCheck.esm.js +2 -4
  22. package/lib/_legacy/PresentationToolGrantsCheck.esm.js.map +1 -1
  23. package/lib/_legacy/presentation.esm.js +3 -3
  24. package/lib/_legacy/presentation.esm.js.map +1 -1
  25. package/lib/_legacy/version.esm.js +1 -1
  26. package/package.json +13 -14
  27. package/src/_internal/cli/server/buildVendorDependencies.ts +1 -0
  28. package/src/_internal/cli/threads/validateDocuments.ts +2 -2
  29. package/src/presentation/PresentationTool.tsx +10 -21
  30. package/src/presentation/constants.ts +4 -16
  31. package/src/presentation/loader/LiveQueries.tsx +79 -234
  32. package/src/presentation/loader/useLiveEvents.ts +75 -0
  33. package/src/presentation/loader/useLiveQueries.ts +127 -0
  34. package/src/presentation/loader/utils.ts +2 -125
  35. package/src/presentation/types.ts +1 -18
  36. package/lib/_chunks-cjs/LoaderQueries.js +0 -281
  37. package/lib/_chunks-cjs/LoaderQueries.js.map +0 -1
  38. package/lib/_chunks-cjs/utils.js +0 -70
  39. package/lib/_chunks-cjs/utils.js.map +0 -1
  40. package/lib/_chunks-es/LoaderQueries.mjs +0 -288
  41. package/lib/_chunks-es/LoaderQueries.mjs.map +0 -1
  42. package/lib/_chunks-es/utils.mjs +0 -74
  43. package/lib/_chunks-es/utils.mjs.map +0 -1
  44. package/lib/_legacy/LoaderQueries.esm.js +0 -288
  45. package/lib/_legacy/LoaderQueries.esm.js.map +0 -1
  46. package/lib/_legacy/utils.esm.js +0 -74
  47. package/lib/_legacy/utils.esm.js.map +0 -1
  48. package/src/presentation/loader/LoaderQueries.tsx +0 -564
@@ -1,136 +1,229 @@
1
1
  "use strict";
2
- var jsxRuntime = require("react/jsx-runtime"), reactCompilerRuntime = require("react-compiler-runtime"), client = require("@sanity/client"), csm = require("@sanity/client/csm"), comlink = require("@sanity/comlink"), presentationComlink = require("@sanity/presentation-comlink"), isEqual = require("fast-deep-equal"), React = require("react"), sanity = require("sanity"), useEffectEvent = require("use-effect-event"), presentation = require("./presentation.js"), utils = require("./utils.js");
2
+ var jsxRuntime = require("react/jsx-runtime"), reactCompilerRuntime = require("react-compiler-runtime"), csm = require("@sanity/client/csm"), comlink = require("@sanity/comlink"), presentationComlink = require("@sanity/presentation-comlink"), isEqual = require("fast-deep-equal"), React = require("react"), sanity = require("sanity"), useEffectEvent = require("use-effect-event"), presentation = require("./presentation.js"), react = require("@portabletext/react"), toolkit = require("@portabletext/toolkit");
3
3
  function _interopDefaultCompat(e) {
4
4
  return e && typeof e == "object" && "default" in e ? e : { default: e };
5
5
  }
6
6
  var isEqual__default = /* @__PURE__ */ _interopDefaultCompat(isEqual);
7
- function LoaderQueries(props) {
8
- const {
9
- liveDocument: _liveDocument,
7
+ function reducer$1(state, event) {
8
+ switch (event.type) {
9
+ case "message":
10
+ return {
11
+ ...state,
12
+ messages: [...state.messages, event]
13
+ };
14
+ case "reconnect":
15
+ case "restart":
16
+ return {
17
+ ...state,
18
+ messages: [],
19
+ resets: state.resets + 1
20
+ };
21
+ case "welcome":
22
+ return state;
23
+ default:
24
+ throw Error(`Unknown event: ${// eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ event.type}`, {
26
+ cause: event
27
+ });
28
+ }
29
+ }
30
+ const initialState$1 = {
31
+ messages: [],
32
+ resets: 0
33
+ };
34
+ function useLiveEvents(client) {
35
+ const $ = reactCompilerRuntime.c(3), [state, dispatch] = React.useReducer(reducer$1, initialState$1), [error, setError] = React.useState(null);
36
+ if (error !== null)
37
+ throw error;
38
+ let t0, t1;
39
+ return $[0] !== client.live ? (t0 = () => {
40
+ const subscription = client.live.events({
41
+ includeDrafts: !0,
42
+ tag: "presentation-loader"
43
+ }).subscribe({
44
+ next: dispatch,
45
+ error: (err) => setError(err instanceof Error ? err : new Error("Unexpected error in useLiveEvents", {
46
+ cause: err
47
+ }))
48
+ });
49
+ return () => subscription.unsubscribe();
50
+ }, t1 = [client.live], $[0] = client.live, $[1] = t0, $[2] = t1) : (t0 = $[1], t1 = $[2]), React.useEffect(t0, t1), React.useDeferredValue(state);
51
+ }
52
+ const mapChangedValue = (changedValue, {
53
+ previousValue
54
+ }) => {
55
+ if (typeof previousValue == "string") {
56
+ if (typeof changedValue == "number")
57
+ return `${changedValue}`;
58
+ if (Array.isArray(changedValue)) {
59
+ if (changedValue.length === 0)
60
+ return "";
61
+ if (changedValue.some((node) => typeof node == "object" && toolkit.isPortableTextBlock(node)))
62
+ return react.toPlainText(changedValue);
63
+ }
64
+ }
65
+ return changedValue;
66
+ };
67
+ function getQueryCacheKey(perspective, query, params) {
68
+ return `${perspective}:${query}:${JSON.stringify(params)}`;
69
+ }
70
+ function gc(state) {
71
+ if (state.queries.size < 1)
72
+ return state;
73
+ const now = Date.now();
74
+ if (!Array.from(state.heartbeats.values()).some((entry) => entry.heartbeat !== !1 && now > entry.receivedAt + entry.heartbeat))
75
+ return state;
76
+ const nextHeartbeats = /* @__PURE__ */ new Map(), nextQueries = /* @__PURE__ */ new Map();
77
+ for (const [key, entry] of state.heartbeats.entries())
78
+ entry.heartbeat !== !1 && now > entry.receivedAt + entry.heartbeat || (nextHeartbeats.set(key, entry), nextQueries.set(key, state.queries.get(key)));
79
+ return {
80
+ ...state,
81
+ queries: nextQueries,
82
+ heartbeats: nextHeartbeats
83
+ };
84
+ }
85
+ function queryListen(state, {
86
+ payload
87
+ }) {
88
+ const key = getQueryCacheKey(payload.perspective, payload.query, payload.params), data = {
89
+ query: payload.query,
90
+ params: payload.params,
91
+ perspective: payload.perspective
92
+ }, nextHeartbeats = new Map(state.heartbeats);
93
+ nextHeartbeats.set(key, {
94
+ receivedAt: Date.now(),
95
+ heartbeat: payload.heartbeat
96
+ });
97
+ let nextQueries = state.queries;
98
+ return (!state.queries.has(key) || !isEqual__default.default(state.queries.get(key), data)) && (nextQueries = new Map(state.queries), nextQueries.set(key, data)), {
99
+ heartbeats: nextHeartbeats,
100
+ queries: nextQueries
101
+ };
102
+ }
103
+ function reducer(state, action) {
104
+ switch (action.type) {
105
+ case "query-listen":
106
+ return queryListen(state, action);
107
+ case "gc":
108
+ return gc(state);
109
+ default:
110
+ throw Error(`Unknown action: ${// eslint-disable-next-line @typescript-eslint/no-explicit-any
111
+ action.type}`, {
112
+ cause: action
113
+ });
114
+ }
115
+ }
116
+ const initialState = {
117
+ queries: /* @__PURE__ */ new Map(),
118
+ heartbeats: /* @__PURE__ */ new Map()
119
+ };
120
+ function useLiveQueries() {
121
+ const $ = reactCompilerRuntime.c(4), [state, dispatch] = React.useReducer(reducer, initialState);
122
+ let t0, t1;
123
+ $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => {
124
+ const interval = setInterval(() => dispatch({
125
+ type: "gc"
126
+ }), presentation.LOADER_QUERY_GC_INTERVAL);
127
+ return () => clearInterval(interval);
128
+ }, t1 = [], $[0] = t0, $[1] = t1) : (t0 = $[0], t1 = $[1]), React.useEffect(t0, t1);
129
+ const queries = React.useDeferredValue(state.queries);
130
+ let t2;
131
+ return $[2] !== queries ? (t2 = [queries, dispatch], $[2] = queries, $[3] = t2) : t2 = $[3], t2;
132
+ }
133
+ function LiveQueries(props) {
134
+ const $ = reactCompilerRuntime.c(30), {
10
135
  controller,
11
136
  perspective: activePerspective,
12
137
  onLoadersConnection,
13
138
  onDocumentsOnPage
14
- } = props, [comlink$1, setComlink] = React.useState(), [liveQueries, setLiveQueries] = React.useState({}), projectId = sanity.useProjectId(), dataset = sanity.useDataset();
15
- React.useEffect(() => {
16
- const interval = setInterval(() => setLiveQueries((liveQueries_0) => {
17
- if (Object.keys(liveQueries_0).length < 1)
18
- return liveQueries_0;
19
- const now = Date.now();
20
- if (!Object.values(liveQueries_0).some(
21
- // eslint-disable-next-line max-nested-callbacks
22
- (liveQuery) => liveQuery.heartbeat !== !1 && now > liveQuery.receivedAt + liveQuery.heartbeat
23
- ))
24
- return liveQueries_0;
25
- const next = {};
26
- for (const [key, value] of Object.entries(liveQueries_0))
27
- value.heartbeat !== !1 && now > value.receivedAt + value.heartbeat || (next[key] = value);
28
- return next;
29
- }), presentation.MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL);
30
- return () => clearInterval(interval);
31
- }, []), React.useEffect(() => {
139
+ } = props, [comlink$1, setComlink] = React.useState(), [liveQueries, liveQueriesDispatch] = useLiveQueries(), projectId = sanity.useProjectId(), dataset = sanity.useDataset();
140
+ let t0, t1;
141
+ $[0] !== controller || $[1] !== dataset || $[2] !== liveQueriesDispatch || $[3] !== onDocumentsOnPage || $[4] !== onLoadersConnection || $[5] !== projectId ? (t0 = () => {
32
142
  if (controller) {
33
- const comlink_0 = controller.createChannel({
143
+ const nextComlink = controller.createChannel({
34
144
  name: "presentation",
35
145
  connectTo: "loaders",
36
146
  heartbeat: !0
37
147
  }, comlink.createConnectionMachine().provide({
38
148
  actors: presentationComlink.createCompatibilityActors()
39
149
  }));
40
- return setComlink(comlink_0), comlink_0.onStatus(onLoadersConnection), comlink_0.on("loader/documents", (data) => {
41
- data.projectId === projectId && data.dataset === dataset && onDocumentsOnPage(
42
- "loaders",
43
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
- data.perspective,
45
- data.documents
46
- );
47
- }), comlink_0.on("loader/query-listen", (data_0) => {
150
+ return setComlink(nextComlink), nextComlink.onStatus(onLoadersConnection), nextComlink.on("loader/documents", (data) => {
151
+ data.projectId === projectId && data.dataset === dataset && onDocumentsOnPage("loaders", data.perspective, data.documents);
152
+ }), nextComlink.on("loader/query-listen", (data_0) => {
48
153
  if (data_0.projectId === projectId && data_0.dataset === dataset) {
49
154
  if (typeof data_0.heartbeat == "number" && data_0.heartbeat < presentation.MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL)
50
155
  throw new Error(`Loader query listen heartbeat interval must be at least ${presentation.MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL}ms`);
51
- setLiveQueries((prev) => ({
52
- ...prev,
53
- [getQueryCacheKey(data_0.query, data_0.params)]: {
156
+ liveQueriesDispatch({
157
+ type: "query-listen",
158
+ payload: {
54
159
  perspective: data_0.perspective,
55
160
  query: data_0.query,
56
161
  params: data_0.params,
57
- receivedAt: Date.now(),
58
162
  heartbeat: data_0.heartbeat ?? !1
59
163
  }
60
- }));
164
+ });
61
165
  }
62
- }), comlink_0.start();
166
+ }), nextComlink.start();
63
167
  }
64
- }, [controller, dataset, onDocumentsOnPage, onLoadersConnection, projectId]);
65
- const [syncTagsInUse] = React.useState(() => /* @__PURE__ */ new Set()), [lastLiveEventId, setLastLiveEventId] = React.useState(null), studioClient = sanity.useClient({
66
- apiVersion: "2023-10-16"
67
- }), clientConfig = React.useMemo(() => studioClient.config(), [studioClient]), client$1 = React.useMemo(() => studioClient.withConfig({
168
+ return _temp;
169
+ }, t1 = [controller, dataset, liveQueriesDispatch, onDocumentsOnPage, onLoadersConnection, projectId], $[0] = controller, $[1] = dataset, $[2] = liveQueriesDispatch, $[3] = onDocumentsOnPage, $[4] = onLoadersConnection, $[5] = projectId, $[6] = t0, $[7] = t1) : (t0 = $[6], t1 = $[7]), React.useEffect(t0, t1);
170
+ let t2;
171
+ $[8] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {
172
+ apiVersion: presentation.API_VERSION
173
+ }, $[8] = t2) : t2 = $[8];
174
+ const studioClient = sanity.useClient(t2);
175
+ let t3, t4;
176
+ $[9] !== studioClient ? (t4 = studioClient.withConfig({
68
177
  resultSourceMap: "withKeyArraySelector"
69
- }), [studioClient]);
70
- React.useEffect(() => {
71
- if (comlink$1) {
72
- const {
73
- projectId: projectId_0,
74
- dataset: dataset_0
75
- } = clientConfig;
76
- comlink$1.post("loader/perspective", {
77
- projectId: projectId_0,
78
- dataset: dataset_0,
79
- perspective: activePerspective
80
- });
81
- }
82
- }, [comlink$1, clientConfig, activePerspective]);
83
- const handleSyncTags = useEffectEvent.useEffectEvent((event) => {
84
- const flattenedSyncTags = Array.from(syncTagsInUse).flat();
85
- event.tags.some((tag) => flattenedSyncTags.includes(tag)) ? setLastLiveEventId(event.id) : console.log("No matching tags found", event.tags, {
86
- flattenedSyncTags
87
- });
88
- });
89
- React.useEffect(() => {
90
- const subscription = client.createClient(client$1.config()).withConfig({
91
- // Necessary for the live drafts to work
92
- apiVersion: "vX"
93
- }).live.events({
94
- includeDrafts: !0,
95
- tag: "presentation-loader"
96
- }).subscribe({
97
- next: (event_0) => {
98
- event_0.type === "message" ? handleSyncTags(event_0) : event_0.type === "restart" ? setLastLiveEventId(event_0.id) : event_0.type === "reconnect" && setLastLiveEventId(null);
99
- },
100
- // eslint-disable-next-line no-console
101
- error: (err) => console.error("Error validating EventSource URL:", err)
178
+ }), $[9] = studioClient, $[10] = t4) : t4 = $[10], t3 = t4;
179
+ const client = t3;
180
+ let t5, t6;
181
+ $[11] !== activePerspective || $[12] !== comlink$1 || $[13] !== dataset || $[14] !== projectId ? (t5 = () => {
182
+ comlink$1 && comlink$1.post("loader/perspective", {
183
+ projectId,
184
+ dataset,
185
+ perspective: activePerspective
102
186
  });
103
- return () => subscription.unsubscribe();
104
- }, [client$1, handleSyncTags]);
105
- const liveDocument = React.useDeferredValue(_liveDocument);
106
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: Object.entries(liveQueries).map(([key_0, {
107
- query,
108
- params,
109
- perspective
110
- }]) => /* @__PURE__ */ jsxRuntime.jsx(QuerySubscription, { projectId: clientConfig.projectId, dataset: clientConfig.dataset, perspective, query, params, comlink: comlink$1, client: client$1, liveDocument, lastLiveEventId, syncTagsInUse }, `${key_0}${perspective}`)) });
187
+ }, t6 = [comlink$1, activePerspective, projectId, dataset], $[11] = activePerspective, $[12] = comlink$1, $[13] = dataset, $[14] = projectId, $[15] = t5, $[16] = t6) : (t5 = $[15], t6 = $[16]), React.useEffect(t5, t6);
188
+ const liveDocument = React.useDeferredValue(props.liveDocument), liveEvents = useLiveEvents(client);
189
+ let t7;
190
+ $[17] !== liveQueries ? (t7 = liveQueries.entries(), $[17] = liveQueries, $[18] = t7) : t7 = $[18];
191
+ let t8;
192
+ $[19] !== t7 ? (t8 = [...t7], $[19] = t7, $[20] = t8) : t8 = $[20];
193
+ let t9;
194
+ return $[21] !== client || $[22] !== comlink$1 || $[23] !== dataset || $[24] !== liveDocument || $[25] !== liveEvents.messages || $[26] !== liveEvents.resets || $[27] !== projectId || $[28] !== t8 ? (t9 = /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: t8.map((t10) => {
195
+ const [key, t11] = t10, {
196
+ query,
197
+ params,
198
+ perspective
199
+ } = t11;
200
+ return /* @__PURE__ */ jsxRuntime.jsx(QuerySubscription, { projectId, dataset, perspective, query, params, comlink: comlink$1, client, liveDocument, liveEventsMessages: liveEvents.messages }, `${liveEvents.resets}:${key}`);
201
+ }) }), $[21] = client, $[22] = comlink$1, $[23] = dataset, $[24] = liveDocument, $[25] = liveEvents.messages, $[26] = liveEvents.resets, $[27] = projectId, $[28] = t8, $[29] = t9) : t9 = $[29], t9;
202
+ }
203
+ function _temp() {
111
204
  }
112
205
  function QuerySubscriptionComponent(props) {
113
- const $ = reactCompilerRuntime.c(14), {
206
+ const $ = reactCompilerRuntime.c(13), {
114
207
  projectId,
115
208
  dataset,
116
209
  perspective,
117
210
  query,
118
- client: client2,
211
+ client,
119
212
  liveDocument,
213
+ params,
120
214
  comlink: comlink2,
121
- lastLiveEventId,
122
- syncTagsInUse
123
- } = props, params = utils.useQueryParams(props.params), {
215
+ liveEventsMessages
216
+ } = props, {
124
217
  result,
125
218
  resultSourceMap,
126
219
  syncTags: tags
127
220
  } = useQuerySubscription({
128
- client: client2,
221
+ client,
129
222
  liveDocument,
130
223
  params,
131
224
  perspective,
132
225
  query,
133
- lastLiveEventId
226
+ liveEventsMessages
134
227
  }) || {};
135
228
  let t0;
136
229
  $[0] !== dataset || $[1] !== projectId ? (t0 = (comlink_0, perspective_0, query_0, params_0, result_0, resultSourceMap_0, tags_0) => {
@@ -147,98 +240,81 @@ function QuerySubscriptionComponent(props) {
147
240
  }, $[0] = dataset, $[1] = projectId, $[2] = t0) : t0 = $[2];
148
241
  const handleQueryChange = useEffectEvent.useEffectEvent(t0);
149
242
  let t1, t2;
150
- return $[3] !== comlink2 || $[4] !== handleQueryChange || $[5] !== params || $[6] !== perspective || $[7] !== query || $[8] !== result || $[9] !== resultSourceMap || $[10] !== syncTagsInUse || $[11] !== tags ? (t1 = () => {
151
- if (resultSourceMap && handleQueryChange(comlink2, perspective, query, params, result, resultSourceMap, tags), Array.isArray(tags))
152
- return syncTagsInUse.add(tags), () => {
153
- syncTagsInUse.delete(tags);
154
- };
155
- }, t2 = [comlink2, handleQueryChange, params, perspective, query, result, resultSourceMap, syncTagsInUse, tags], $[3] = comlink2, $[4] = handleQueryChange, $[5] = params, $[6] = perspective, $[7] = query, $[8] = result, $[9] = resultSourceMap, $[10] = syncTagsInUse, $[11] = tags, $[12] = t1, $[13] = t2) : (t1 = $[12], t2 = $[13]), React.useEffect(t1, t2), null;
243
+ return $[3] !== comlink2 || $[4] !== handleQueryChange || $[5] !== params || $[6] !== perspective || $[7] !== query || $[8] !== result || $[9] !== resultSourceMap || $[10] !== tags ? (t1 = () => {
244
+ resultSourceMap && handleQueryChange(comlink2, perspective, query, params, result, resultSourceMap, tags);
245
+ }, t2 = [comlink2, handleQueryChange, params, perspective, query, result, resultSourceMap, tags], $[3] = comlink2, $[4] = handleQueryChange, $[5] = params, $[6] = perspective, $[7] = query, $[8] = result, $[9] = resultSourceMap, $[10] = tags, $[11] = t1, $[12] = t2) : (t1 = $[11], t2 = $[12]), React.useEffect(t1, t2), null;
156
246
  }
157
247
  const QuerySubscription = React.memo(QuerySubscriptionComponent);
158
248
  QuerySubscription.displayName = "Memo(QuerySubscription)";
159
249
  function useQuerySubscription(props) {
160
- const $ = reactCompilerRuntime.c(25), {
250
+ const $ = reactCompilerRuntime.c(30), {
161
251
  liveDocument,
162
- client: client2,
252
+ client,
163
253
  query,
164
254
  params,
165
255
  perspective,
166
- lastLiveEventId
167
- } = props, [snapshot, setSnapshot] = React.useState(null), [error, setError] = React.useState(null);
256
+ liveEventsMessages
257
+ } = props, [result, setResult] = React.useState(null), [resultSourceMap, setResultSourceMap] = React.useState(null), [syncTags, setSyncTags] = React.useState(void 0);
258
+ let t0;
259
+ $[0] !== liveEventsMessages ? (t0 = () => new Set(liveEventsMessages.map(_temp2)), $[0] = liveEventsMessages, $[1] = t0) : t0 = $[1];
260
+ const [skipEventIds] = React.useState(t0);
261
+ let t1;
262
+ if ($[2] !== liveEventsMessages || $[3] !== skipEventIds || $[4] !== syncTags) {
263
+ let t22;
264
+ $[6] !== skipEventIds ? (t22 = (msg_0) => !skipEventIds.has(msg_0.id), $[6] = skipEventIds, $[7] = t22) : t22 = $[7];
265
+ const recentLiveEvents = liveEventsMessages.filter(t22);
266
+ let t32;
267
+ $[8] !== syncTags ? (t32 = (msg_1) => msg_1.tags.some((tag) => syncTags?.includes(tag)), $[8] = syncTags, $[9] = t32) : t32 = $[9], t1 = recentLiveEvents.findLast(t32), $[2] = liveEventsMessages, $[3] = skipEventIds, $[4] = syncTags, $[5] = t1;
268
+ } else
269
+ t1 = $[5];
270
+ const lastLiveEventId = t1?.id, [error, setError] = React.useState(null);
168
271
  if (error)
169
272
  throw error;
170
- let t0;
171
- $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
172
- refreshInterval: 0
173
- }, $[0] = t0) : t0 = $[0];
174
- const [revalidate, startRefresh] = utils.useRevalidate(t0), shouldRefetch = revalidate === "refresh" || revalidate === "inflight" || lastLiveEventId !== snapshot?.lastLiveEventId;
175
- let t1, t2;
176
- $[1] !== client2 || $[2] !== lastLiveEventId || $[3] !== params || $[4] !== perspective || $[5] !== query || $[6] !== shouldRefetch || $[7] !== startRefresh ? (t1 = () => {
177
- if (!shouldRefetch)
178
- return;
179
- let fulfilled;
180
- fulfilled = !1;
181
- let fetching;
182
- fetching = !1;
183
- const controller = new AbortController(), effect = async function() {
184
- const {
185
- signal
186
- } = controller;
187
- fetching = !0;
188
- const {
189
- result,
190
- resultSourceMap,
191
- syncTags
192
- } = await client2.fetch(query, params, {
193
- lastLiveEventId,
194
- tag: "presentation-loader",
195
- signal,
196
- perspective,
197
- filterResponse: !1,
198
- returnQuery: !1
273
+ let t2, t3;
274
+ $[10] !== client || $[11] !== lastLiveEventId || $[12] !== params || $[13] !== perspective || $[14] !== query ? (t2 = () => {
275
+ const controller = new AbortController();
276
+ return client.fetch(query, params, {
277
+ lastLiveEventId,
278
+ tag: "presentation-loader",
279
+ signal: controller.signal,
280
+ perspective,
281
+ filterResponse: !1,
282
+ returnQuery: !1
283
+ }).then((response) => {
284
+ React.startTransition(() => {
285
+ setResult((prev) => isEqual__default.default(prev, response.result) ? prev : response.result), setResultSourceMap((prev_0) => isEqual__default.default(prev_0, response.resultSourceMap) ? prev_0 : response.resultSourceMap), setSyncTags((prev_1) => isEqual__default.default(prev_1, response.syncTags) ? prev_1 : response.syncTags);
199
286
  });
200
- fetching = !1, signal.aborted || (setSnapshot((prev) => ({
201
- result: isEqual__default.default(prev?.result, result) ? prev?.result : result,
202
- resultSourceMap: isEqual__default.default(prev?.resultSourceMap, resultSourceMap) ? prev?.resultSourceMap : resultSourceMap,
203
- syncTags: isEqual__default.default(prev?.syncTags, syncTags) ? prev?.syncTags : syncTags,
204
- lastLiveEventId
205
- })), fulfilled = !0);
206
- }, onFinally = startRefresh();
207
- return effect().catch((error_0) => {
208
- fetching = !1, error_0.name !== "AbortError" && setError(error_0);
209
- }).finally(onFinally), () => {
210
- !fulfilled && !fetching && controller.abort();
287
+ }).catch((err) => {
288
+ (typeof err != "object" || err?.name !== "AbortError") && setError(err);
289
+ }), () => {
290
+ controller.abort();
211
291
  };
212
- }, t2 = [client2, lastLiveEventId, params, perspective, query, shouldRefetch, startRefresh], $[1] = client2, $[2] = lastLiveEventId, $[3] = params, $[4] = perspective, $[5] = query, $[6] = shouldRefetch, $[7] = startRefresh, $[8] = t1, $[9] = t2) : (t1 = $[8], t2 = $[9]), React.useEffect(t1, t2);
213
- let t3;
214
- $[10] !== snapshot ? (t3 = snapshot ?? {}, $[10] = snapshot, $[11] = t3) : t3 = $[11];
215
- const {
216
- result: result_0,
217
- resultSourceMap: resultSourceMap_0,
218
- syncTags: syncTags_0
219
- } = t3;
292
+ }, t3 = [client, lastLiveEventId, params, perspective, query], $[10] = client, $[11] = lastLiveEventId, $[12] = params, $[13] = perspective, $[14] = query, $[15] = t2, $[16] = t3) : (t2 = $[15], t3 = $[16]), React.useEffect(t2, t3);
220
293
  let t4;
221
294
  bb0: {
222
- if (liveDocument && resultSourceMap_0) {
295
+ if (liveDocument && resultSourceMap) {
223
296
  let t52;
224
- $[12] !== liveDocument || $[13] !== perspective || $[14] !== resultSourceMap_0 || $[15] !== result_0 ? (t52 = turboChargeResultIfSourceMap(liveDocument, result_0, perspective, resultSourceMap_0), $[12] = liveDocument, $[13] = perspective, $[14] = resultSourceMap_0, $[15] = result_0, $[16] = t52) : t52 = $[16];
297
+ $[17] !== liveDocument || $[18] !== perspective || $[19] !== result || $[20] !== resultSourceMap ? (t52 = turboChargeResultIfSourceMap(liveDocument, result, perspective, resultSourceMap), $[17] = liveDocument, $[18] = perspective, $[19] = result, $[20] = resultSourceMap, $[21] = t52) : t52 = $[21];
225
298
  let t6;
226
- $[17] !== resultSourceMap_0 || $[18] !== syncTags_0 || $[19] !== t52 ? (t6 = {
299
+ $[22] !== resultSourceMap || $[23] !== syncTags || $[24] !== t52 ? (t6 = {
227
300
  result: t52,
228
- resultSourceMap: resultSourceMap_0,
229
- syncTags: syncTags_0
230
- }, $[17] = resultSourceMap_0, $[18] = syncTags_0, $[19] = t52, $[20] = t6) : t6 = $[20], t4 = t6;
301
+ resultSourceMap,
302
+ syncTags
303
+ }, $[22] = resultSourceMap, $[23] = syncTags, $[24] = t52, $[25] = t6) : t6 = $[25], t4 = t6;
231
304
  break bb0;
232
305
  }
233
306
  let t5;
234
- $[21] !== resultSourceMap_0 || $[22] !== result_0 || $[23] !== syncTags_0 ? (t5 = {
235
- result: result_0,
236
- resultSourceMap: resultSourceMap_0,
237
- syncTags: syncTags_0
238
- }, $[21] = resultSourceMap_0, $[22] = result_0, $[23] = syncTags_0, $[24] = t5) : t5 = $[24], t4 = t5;
307
+ $[26] !== result || $[27] !== resultSourceMap || $[28] !== syncTags ? (t5 = {
308
+ result,
309
+ resultSourceMap,
310
+ syncTags
311
+ }, $[26] = result, $[27] = resultSourceMap, $[28] = syncTags, $[29] = t5) : t5 = $[29], t4 = t5;
239
312
  }
240
313
  return t4;
241
314
  }
315
+ function _temp2(msg) {
316
+ return msg.id;
317
+ }
242
318
  function turboChargeResultIfSourceMap(liveDocument, result, perspective, resultSourceMap) {
243
319
  if (perspective === "raw")
244
320
  throw new Error("turboChargeResultIfSourceMap does not support raw perspective");
@@ -249,11 +325,8 @@ function turboChargeResultIfSourceMap(liveDocument, result, perspective, resultS
249
325
  _id: liveDocument._id || sourceDocument._id,
250
326
  _type: liveDocument._type || sourceDocument._type
251
327
  } : null
252
- ), utils.mapChangedValue, perspective);
253
- }
254
- function getQueryCacheKey(query, params) {
255
- return `${query}-${typeof params == "string" ? params : JSON.stringify(params)}`;
328
+ ), mapChangedValue, perspective);
256
329
  }
257
- exports.default = LoaderQueries;
330
+ exports.default = LiveQueries;
258
331
  exports.turboChargeResultIfSourceMap = turboChargeResultIfSourceMap;
259
332
  //# sourceMappingURL=LiveQueries.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LiveQueries.js","sources":["../../src/presentation/loader/LiveQueries.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-shadow */\nimport {\n type ClientPerspective,\n type ContentSourceMap,\n createClient,\n type LiveEventMessage,\n type QueryParams,\n type SyncTag,\n} from '@sanity/client'\nimport {applySourceDocuments, getPublishedId} from '@sanity/client/csm'\nimport {\n type ChannelInstance,\n type Controller,\n createConnectionMachine,\n type StatusEvent,\n} from '@sanity/comlink'\nimport {\n createCompatibilityActors,\n type LoaderControllerMsg,\n type LoaderNodeMsg,\n} from '@sanity/presentation-comlink'\nimport isEqual from 'fast-deep-equal'\n// import {createPreviewSecret} from '@sanity/preview-url-secret/create-secret'\nimport {memo, useDeferredValue, useEffect, useMemo, useState} from 'react'\nimport {\n type SanityClient,\n type SanityDocument,\n useClient,\n // useCurrentUser,\n useDataset,\n useProjectId,\n} from 'sanity'\nimport {useEffectEvent} from 'use-effect-event'\n\n// import {useEffectEvent} from 'use-effect-event'\nimport {MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL} from '../constants'\nimport {\n type LiveQueriesState,\n type LiveQueriesStateValue,\n type LoaderConnection,\n type PresentationPerspective,\n} from '../types'\nimport {type DocumentOnPage} from '../useDocumentsOnPage'\nimport {mapChangedValue, useQueryParams, useRevalidate} from './utils'\n\nexport interface LoaderQueriesProps {\n liveDocument: Partial<SanityDocument> | null | undefined\n controller: Controller | undefined\n perspective: ClientPerspective\n onLoadersConnection: (event: StatusEvent) => void\n onDocumentsOnPage: (\n key: string,\n perspective: PresentationPerspective,\n state: DocumentOnPage[],\n ) => void\n}\n\nexport default function LoaderQueries(props: LoaderQueriesProps): React.JSX.Element {\n const {\n liveDocument: _liveDocument,\n controller,\n perspective: activePerspective,\n onLoadersConnection,\n onDocumentsOnPage,\n } = props\n\n const [comlink, setComlink] = useState<ChannelInstance<LoaderControllerMsg, LoaderNodeMsg>>()\n const [liveQueries, setLiveQueries] = useState<LiveQueriesState>({})\n\n const projectId = useProjectId()\n const dataset = useDataset()\n\n useEffect(() => {\n const interval = setInterval(\n () =>\n setLiveQueries((liveQueries) => {\n if (Object.keys(liveQueries).length < 1) {\n return liveQueries\n }\n\n const now = Date.now()\n const hasAnyExpired = Object.values(liveQueries).some(\n // eslint-disable-next-line max-nested-callbacks\n (liveQuery) =>\n liveQuery.heartbeat !== false && now > liveQuery.receivedAt + liveQuery.heartbeat,\n )\n if (!hasAnyExpired) {\n return liveQueries\n }\n const next = {} as LiveQueriesState\n for (const [key, value] of Object.entries(liveQueries)) {\n if (value.heartbeat !== false && now > value.receivedAt + value.heartbeat) {\n continue\n }\n next[key] = value\n }\n return next\n }),\n MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL,\n )\n return () => clearInterval(interval)\n }, [])\n\n useEffect(() => {\n if (controller) {\n const comlink = controller.createChannel<LoaderControllerMsg, LoaderNodeMsg>(\n {\n name: 'presentation',\n connectTo: 'loaders',\n heartbeat: true,\n },\n createConnectionMachine<LoaderControllerMsg, LoaderNodeMsg>().provide({\n actors: createCompatibilityActors<LoaderControllerMsg>(),\n }),\n )\n setComlink(comlink)\n\n comlink.onStatus(onLoadersConnection)\n\n comlink.on('loader/documents', (data) => {\n if (data.projectId === projectId && data.dataset === dataset) {\n onDocumentsOnPage(\n 'loaders',\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n data.perspective as unknown as any,\n data.documents,\n )\n }\n })\n\n comlink.on('loader/query-listen', (data) => {\n if (data.projectId === projectId && data.dataset === dataset) {\n if (\n typeof data.heartbeat === 'number' &&\n data.heartbeat < MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL\n ) {\n throw new Error(\n `Loader query listen heartbeat interval must be at least ${MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL}ms`,\n )\n }\n setLiveQueries((prev) => ({\n ...prev,\n [getQueryCacheKey(data.query, data.params)]: {\n perspective: data.perspective,\n query: data.query,\n params: data.params,\n receivedAt: Date.now(),\n heartbeat: data.heartbeat ?? false,\n } satisfies LiveQueriesStateValue,\n }))\n }\n })\n\n return comlink.start()\n }\n return undefined\n }, [controller, dataset, onDocumentsOnPage, onLoadersConnection, projectId])\n\n // const currentUser = useCurrentUser()\n // const handleCreatePreviewUrlSecret = useEffectEvent(\n // async ({projectId, dataset}: {projectId: string; dataset: string}) => {\n // try {\n // // eslint-disable-next-line no-console\n // console.log('Creating preview URL secret for ', {projectId, dataset})\n // const {secret} = await createPreviewSecret(\n // client,\n // '@sanity/presentation',\n // typeof window === 'undefined' ? '' : location.href,\n // currentUser?.id,\n // )\n // return {secret}\n // } catch (err) {\n // // eslint-disable-next-line no-console\n // console.error('Failed to generate preview URL secret', err)\n // return {secret: null}\n // }\n // },\n // )\n // useEffect(() => {\n // return comlink?.on('loader/fetch-preview-url-secret', (data) =>\n // handleCreatePreviewUrlSecret(data),\n // )\n // }, [comlink, handleCreatePreviewUrlSecret])\n\n const [syncTagsInUse] = useState(() => new Set<SyncTag[]>())\n const [lastLiveEventId, setLastLiveEventId] = useState<string | null>(null)\n const studioClient = useClient({apiVersion: '2023-10-16'})\n const clientConfig = useMemo(() => studioClient.config(), [studioClient])\n const client = useMemo(\n () =>\n studioClient.withConfig({\n resultSourceMap: 'withKeyArraySelector',\n }),\n [studioClient],\n )\n useEffect(() => {\n if (comlink) {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const {projectId, dataset} = clientConfig\n comlink.post('loader/perspective', {\n projectId: projectId!,\n dataset: dataset!,\n perspective: activePerspective,\n })\n }\n }, [comlink, clientConfig, activePerspective])\n\n const handleSyncTags = useEffectEvent((event: LiveEventMessage) => {\n const flattenedSyncTags = Array.from(syncTagsInUse).flat()\n const hasMatchingTags = event.tags.some((tag) => flattenedSyncTags.includes(tag))\n if (hasMatchingTags) {\n setLastLiveEventId(event.id)\n } else {\n // eslint-disable-next-line no-console\n console.log('No matching tags found', event.tags, {flattenedSyncTags})\n }\n })\n useEffect(() => {\n const liveClient = createClient(client.config()).withConfig({\n // Necessary for the live drafts to work\n apiVersion: 'vX',\n })\n const subscription = liveClient.live\n .events({includeDrafts: true, tag: 'presentation-loader'})\n .subscribe({\n next: (event) => {\n if (event.type === 'message') {\n handleSyncTags(event)\n } else if (event.type === 'restart') {\n setLastLiveEventId(event.id)\n } else if (event.type === 'reconnect') {\n setLastLiveEventId(null)\n }\n },\n // eslint-disable-next-line no-console\n error: (err) => console.error('Error validating EventSource URL:', err),\n })\n return () => subscription.unsubscribe()\n }, [client, handleSyncTags])\n\n /**\n * Defer the liveDocument to avoid unnecessary rerenders on rapid edits\n */\n const liveDocument = useDeferredValue(_liveDocument)\n\n return (\n <>\n {Object.entries(liveQueries).map(([key, {query, params, perspective}]) => (\n <QuerySubscription\n key={`${key}${perspective}`}\n projectId={clientConfig.projectId!}\n dataset={clientConfig.dataset!}\n perspective={perspective}\n query={query}\n params={params}\n comlink={comlink}\n client={client}\n liveDocument={liveDocument}\n lastLiveEventId={lastLiveEventId}\n syncTagsInUse={syncTagsInUse}\n />\n ))}\n </>\n )\n}\n\ninterface SharedProps {\n /**\n * The Sanity client to use for fetching data and listening to mutations.\n */\n client: SanityClient\n}\n\ninterface QuerySubscriptionProps\n extends Pick<UseQuerySubscriptionProps, 'client' | 'liveDocument' | 'lastLiveEventId'> {\n projectId: string\n dataset: string\n perspective: ClientPerspective\n query: string\n params: QueryParams\n comlink: LoaderConnection | undefined\n syncTagsInUse: Set<SyncTag[]>\n}\nfunction QuerySubscriptionComponent(props: QuerySubscriptionProps) {\n const {\n projectId,\n dataset,\n perspective,\n query,\n client,\n liveDocument,\n comlink,\n lastLiveEventId,\n syncTagsInUse,\n } = props\n\n const params = useQueryParams(props.params)\n const {\n result,\n resultSourceMap,\n syncTags: tags,\n } = useQuerySubscription({\n client,\n liveDocument,\n params,\n perspective,\n query,\n lastLiveEventId,\n }) || {}\n\n const handleQueryChange = useEffectEvent(\n (\n comlink: LoaderConnection | undefined,\n perspective: ClientPerspective,\n query: string,\n params: QueryParams,\n result: unknown,\n resultSourceMap: ContentSourceMap | undefined,\n tags: `s1:${string}`[] | undefined,\n // eslint-disable-next-line max-params\n ) => {\n comlink?.post('loader/query-change', {\n projectId,\n dataset,\n perspective,\n query,\n params,\n result,\n resultSourceMap,\n tags,\n })\n },\n )\n useEffect(() => {\n if (resultSourceMap) {\n handleQueryChange(comlink, perspective, query, params, result, resultSourceMap, tags)\n }\n if (Array.isArray(tags)) {\n syncTagsInUse.add(tags)\n return () => {\n syncTagsInUse.delete(tags)\n }\n }\n return undefined\n }, [\n comlink,\n handleQueryChange,\n params,\n perspective,\n query,\n result,\n resultSourceMap,\n syncTagsInUse,\n tags,\n ])\n\n return null\n}\nconst QuerySubscription = memo(QuerySubscriptionComponent)\nQuerySubscription.displayName = 'Memo(QuerySubscription)'\n\ninterface UseQuerySubscriptionProps extends Required<Pick<SharedProps, 'client'>> {\n liveDocument: Partial<SanityDocument> | null | undefined\n query: string\n params: QueryParams\n perspective: ClientPerspective\n lastLiveEventId: string | null\n}\nfunction useQuerySubscription(props: UseQuerySubscriptionProps) {\n const {liveDocument, client, query, params, perspective, lastLiveEventId} = props\n const [snapshot, setSnapshot] = useState<{\n result: unknown\n resultSourceMap?: ContentSourceMap\n syncTags?: SyncTag[]\n lastLiveEventId: string | null\n } | null>(null)\n // Make sure any async errors bubble up to the nearest error boundary\n const [error, setError] = useState<unknown>(null)\n if (error) throw error\n\n const [revalidate, startRefresh] = useRevalidate({\n // Refresh interval is set to zero as we're using the Live Draft Content API to revalidate queries\n refreshInterval: 0,\n })\n const shouldRefetch =\n revalidate === 'refresh' ||\n revalidate === 'inflight' ||\n lastLiveEventId !== snapshot?.lastLiveEventId\n useEffect(() => {\n if (!shouldRefetch) {\n return undefined\n }\n\n let fulfilled = false\n let fetching = false\n const controller = new AbortController()\n // eslint-disable-next-line no-inner-declarations\n async function effect() {\n const {signal} = controller\n fetching = true\n const {result, resultSourceMap, syncTags} = await client.fetch(query, params, {\n lastLiveEventId,\n tag: 'presentation-loader',\n signal,\n perspective,\n filterResponse: false,\n returnQuery: false,\n })\n fetching = false\n\n if (!signal.aborted) {\n setSnapshot((prev) => ({\n result: isEqual(prev?.result, result) ? prev?.result : result,\n resultSourceMap: isEqual(prev?.resultSourceMap, resultSourceMap)\n ? prev?.resultSourceMap\n : resultSourceMap,\n syncTags: isEqual(prev?.syncTags, syncTags) ? prev?.syncTags : syncTags,\n lastLiveEventId,\n }))\n fulfilled = true\n }\n }\n const onFinally = startRefresh()\n effect()\n .catch((error) => {\n fetching = false\n if (error.name !== 'AbortError') {\n setError(error)\n }\n })\n .finally(onFinally)\n return () => {\n if (!fulfilled && !fetching) {\n controller.abort()\n }\n }\n }, [client, lastLiveEventId, params, perspective, query, shouldRefetch, startRefresh])\n\n const {result, resultSourceMap, syncTags} = snapshot ?? {}\n return useMemo(() => {\n if (liveDocument && resultSourceMap) {\n return {\n result: turboChargeResultIfSourceMap(liveDocument, result, perspective, resultSourceMap),\n resultSourceMap,\n syncTags,\n }\n }\n return {result, resultSourceMap, syncTags}\n }, [liveDocument, perspective, result, resultSourceMap, syncTags])\n}\n\nexport function turboChargeResultIfSourceMap<T = unknown>(\n liveDocument: Partial<SanityDocument> | null | undefined,\n result: T,\n perspective: ClientPerspective,\n resultSourceMap?: ContentSourceMap,\n): T {\n if (perspective === 'raw') {\n throw new Error('turboChargeResultIfSourceMap does not support raw perspective')\n }\n return applySourceDocuments(\n result,\n resultSourceMap,\n (sourceDocument) => {\n // If there's a displayed document, always prefer it\n if (\n // If _projectId is set, it's a cross dataset reference and we should skip it\n !sourceDocument._projectId &&\n liveDocument?._id &&\n getPublishedId(liveDocument._id) === getPublishedId(sourceDocument._id)\n ) {\n if (typeof liveDocument._id === 'string' && typeof sourceDocument._type === 'string') {\n return liveDocument as unknown as Required<Pick<SanityDocument, '_id' | '_type'>>\n }\n return {\n ...liveDocument,\n _id: liveDocument._id || sourceDocument._id,\n _type: liveDocument._type || sourceDocument._type,\n }\n }\n return null\n },\n mapChangedValue,\n perspective,\n )\n}\n\nfunction getQueryCacheKey(query: string, params: QueryParams | string): `${string}-${string}` {\n return `${query}-${typeof params === 'string' ? params : JSON.stringify(params)}`\n}\n"],"names":["LoaderQueries","props","liveDocument","_liveDocument","controller","perspective","activePerspective","onLoadersConnection","onDocumentsOnPage","comlink","setComlink","useState","liveQueries","setLiveQueries","projectId","useProjectId","dataset","useDataset","useEffect","interval","setInterval","Object","keys","length","now","Date","values","some","liveQuery","heartbeat","receivedAt","next","key","value","entries","MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL","clearInterval","createChannel","name","connectTo","createConnectionMachine","provide","actors","createCompatibilityActors","onStatus","on","data","documents","Error","prev","getQueryCacheKey","query","params","start","syncTagsInUse","Set","lastLiveEventId","setLastLiveEventId","studioClient","useClient","apiVersion","clientConfig","useMemo","config","client","withConfig","resultSourceMap","post","handleSyncTags","useEffectEvent","event","flattenedSyncTags","Array","from","flat","tags","tag","includes","id","console","log","subscription","createClient","live","events","includeDrafts","subscribe","type","error","err","unsubscribe","useDeferredValue","jsx","Fragment","map","QuerySubscriptionComponent","$","_c","useQueryParams","result","syncTags","useQuerySubscription","t0","comlink_0","perspective_0","query_0","params_0","result_0","resultSourceMap_0","tags_0","handleQueryChange","t1","t2","isArray","add","delete","QuerySubscription","memo","displayName","snapshot","setSnapshot","setError","Symbol","for","refreshInterval","revalidate","startRefresh","useRevalidate","shouldRefetch","fulfilled","fetching","AbortController","effect","signal","fetch","filterResponse","returnQuery","aborted","isEqual","onFinally","catch","error_0","finally","abort","t3","syncTags_0","t4","t5","turboChargeResultIfSourceMap","t6","bb0","applySourceDocuments","sourceDocument","_projectId","_id","getPublishedId","_type","mapChangedValue","JSON","stringify"],"mappings":"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"}
1
+ {"version":3,"file":"LiveQueries.js","sources":["../../src/presentation/loader/useLiveEvents.ts","../../src/presentation/loader/utils.ts","../../src/presentation/loader/useLiveQueries.ts","../../src/presentation/loader/LiveQueries.tsx"],"sourcesContent":["import {type LiveEvent, type LiveEventMessage} from '@sanity/client'\nimport {useDeferredValue, useEffect, useReducer, useState} from 'react'\nimport {type SanityClient} from 'sanity'\n\ntype State = {\n /**\n * Growing list over live events with Sync Tags,\n * that can be used to refetch with Sanity Client, using the id as the lastLiveEventId parameter\n */\n messages: LiveEventMessage[]\n /**\n * If the connection experiences a reconnect, or a restart event is received, the counter is incremented.\n * This counter is suitable as a `key` on React Components as a way to reset its internal state and refetch.\n */\n resets: number\n}\n\nexport function reducer(state: State, event: LiveEvent): State {\n switch (event.type) {\n case 'message':\n return {\n ...state,\n messages: [...state.messages, event],\n }\n case 'reconnect':\n case 'restart':\n return {\n ...state,\n messages: [],\n resets: state.resets + 1,\n }\n case 'welcome':\n // no-op\n return state\n default:\n throw Error(\n `Unknown event: ${\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (event as any).type\n }`,\n {cause: event},\n )\n }\n}\n\nexport const initialState: State = {\n messages: [],\n resets: 0,\n}\n\nexport function useLiveEvents(client: SanityClient): State {\n const [state, dispatch] = useReducer(reducer, initialState)\n const [error, setError] = useState<unknown>(null)\n if (error !== null) {\n // Push error to nearest error boundary\n throw error\n }\n\n useEffect(() => {\n const subscription = client.live\n .events({includeDrafts: true, tag: 'presentation-loader'})\n .subscribe({\n next: dispatch,\n error: (err) =>\n setError(\n err instanceof Error\n ? err\n : new Error('Unexpected error in useLiveEvents', {cause: err}),\n ),\n })\n return () => subscription.unsubscribe()\n }, [client.live])\n\n return useDeferredValue(state)\n}\n","import {toPlainText} from '@portabletext/react'\nimport {isPortableTextBlock} from '@portabletext/toolkit'\nimport {type ClientPerspective, type QueryParams} from '@sanity/client'\nimport {type ApplySourceDocumentsUpdateFunction} from '@sanity/client/csm'\nimport {type FIXME} from 'sanity'\n\n/**\n * Used by `applySourceDocuments`\n * @internal\n */\nexport const mapChangedValue: ApplySourceDocumentsUpdateFunction = (\n changedValue: FIXME,\n {previousValue},\n) => {\n if (typeof previousValue === 'string') {\n if (typeof changedValue === 'number') {\n // If the string() function was used in the query, we need to convert the source value to a string as well\n return `${changedValue}`\n }\n // If it's an array in the source, but a string in the query response, it could be pt::text\n if (Array.isArray(changedValue)) {\n if (changedValue.length === 0) {\n // If it's empty assume it's PT and return an empty string\n return ''\n }\n // If the array contains any valid block type, assume the GROQ initially used pt::text on it and do the same conversion\n if (changedValue.some((node) => typeof node === 'object' && isPortableTextBlock(node))) {\n return toPlainText(changedValue)\n }\n }\n }\n\n return changedValue\n}\n\n/**\n * @internal\n */\nexport type QueryCacheKey = `${string}:${string}:${string}`\n/**\n * @internal\n */\nexport function getQueryCacheKey(\n perspective: ClientPerspective,\n query: string,\n params: QueryParams,\n): QueryCacheKey {\n return `${perspective}:${query}:${JSON.stringify(params)}`\n}\n","import {type ClientPerspective} from '@sanity/client'\nimport isEqual from 'fast-deep-equal'\nimport {useDeferredValue, useEffect, useReducer} from 'react'\nimport {type QueryParams} from 'sanity'\n\nimport {LOADER_QUERY_GC_INTERVAL} from '../constants'\nimport {getQueryCacheKey, type QueryCacheKey} from './utils'\n\ntype LiveQueriesState = Map<\n QueryCacheKey,\n {\n query: string\n params: QueryParams\n perspective: ClientPerspective\n }\n>\n\ntype State = {\n queries: LiveQueriesState\n heartbeats: Map<\n QueryCacheKey,\n {\n receivedAt: number\n /**\n * If false it means the query can't safely be garbage collected,\n * as older versions of \\@sanity/core-loader doesn't fire listen events\n * on an interval.\n */\n heartbeat: number | false\n }\n >\n}\n\ntype QueryListenAction = {\n type: 'query-listen'\n payload: {\n perspective: ClientPerspective\n query: string\n params: QueryParams\n heartbeat: number | false\n }\n}\ntype GarbageCollectAction = {type: 'gc'}\ntype Action = QueryListenAction | GarbageCollectAction\n\nfunction gc(state: State): State {\n if (state.queries.size < 1) {\n return state\n }\n\n const now = Date.now()\n const hasAnyExpired = Array.from(state.heartbeats.values()).some(\n (entry) => entry.heartbeat !== false && now > entry.receivedAt + entry.heartbeat,\n )\n if (!hasAnyExpired) {\n return state\n }\n const nextHeartbeats = new Map()\n const nextQueries = new Map()\n for (const [key, entry] of state.heartbeats.entries()) {\n if (entry.heartbeat !== false && now > entry.receivedAt + entry.heartbeat) {\n continue\n }\n nextHeartbeats.set(key, entry)\n nextQueries.set(key, state.queries.get(key))\n }\n\n return {...state, queries: nextQueries, heartbeats: nextHeartbeats}\n}\nfunction queryListen(state: State, {payload}: QueryListenAction): State {\n const key = getQueryCacheKey(payload.perspective, payload.query, payload.params)\n const data = {query: payload.query, params: payload.params, perspective: payload.perspective}\n\n const nextHeartbeats = new Map(state.heartbeats)\n nextHeartbeats.set(key, {\n receivedAt: Date.now(),\n heartbeat: payload.heartbeat,\n })\n\n let nextQueries = state.queries\n /**\n * The data comes from a postMessage event, which uses the structured clone algorithm to serialize state (https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#message).\n * This impacts `params`, which is an object, as it will be a new object every time even if the sender is sending the same object instance on their end.\n * It also impacts `perspective`, as it's no longer just a string, but can also be an array of strings.\n * Both cases are handled by fast-deep-equal, which is used to compare the data before deciding wether the state should be updated.\n */\n if (!state.queries.has(key) || !isEqual(state.queries.get(key), data)) {\n nextQueries = new Map(state.queries)\n nextQueries.set(key, data)\n }\n\n return {heartbeats: nextHeartbeats, queries: nextQueries}\n}\n\nexport function reducer(state: State, action: Action): State {\n switch (action.type) {\n case 'query-listen':\n return queryListen(state, action)\n case 'gc':\n return gc(state)\n default:\n throw Error(\n `Unknown action: ${\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (action as any).type\n }`,\n {cause: action},\n )\n }\n}\n\nexport const initialState: State = {\n queries: new Map(),\n heartbeats: new Map(),\n}\n\nexport function useLiveQueries(): [LiveQueriesState, React.ActionDispatch<[action: Action]>] {\n const [state, dispatch] = useReducer(reducer, initialState)\n\n useEffect(() => {\n const interval = setInterval(() => dispatch({type: 'gc'}), LOADER_QUERY_GC_INTERVAL)\n return () => clearInterval(interval)\n }, [])\n\n const queries = useDeferredValue(state.queries)\n return [queries, dispatch]\n}\n","import {\n type ClientPerspective,\n type ContentSourceMap,\n type LiveEventMessage,\n type QueryParams,\n type SyncTag,\n} from '@sanity/client'\nimport {applySourceDocuments, getPublishedId} from '@sanity/client/csm'\nimport {\n type ChannelInstance,\n type Controller,\n createConnectionMachine,\n type StatusEvent,\n} from '@sanity/comlink'\nimport {\n createCompatibilityActors,\n type LoaderControllerMsg,\n type LoaderNodeMsg,\n} from '@sanity/presentation-comlink'\nimport isEqual from 'fast-deep-equal'\nimport {memo, startTransition, useDeferredValue, useEffect, useMemo, useState} from 'react'\nimport {type SanityClient, type SanityDocument, useClient, useDataset, useProjectId} from 'sanity'\nimport {useEffectEvent} from 'use-effect-event'\n\nimport {API_VERSION, MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL} from '../constants'\nimport {type LoaderConnection, type PresentationPerspective} from '../types'\nimport {type DocumentOnPage} from '../useDocumentsOnPage'\nimport {useLiveEvents} from './useLiveEvents'\nimport {useLiveQueries} from './useLiveQueries'\nimport {mapChangedValue} from './utils'\n\nexport interface LiveQueriesProps {\n liveDocument: Partial<SanityDocument> | null | undefined\n controller: Controller | undefined\n perspective: ClientPerspective\n onLoadersConnection: (event: StatusEvent) => void\n onDocumentsOnPage: (\n key: string,\n perspective: PresentationPerspective,\n state: DocumentOnPage[],\n ) => void\n}\n\nexport default function LiveQueries(props: LiveQueriesProps): React.JSX.Element {\n const {controller, perspective: activePerspective, onLoadersConnection, onDocumentsOnPage} = props\n\n const [comlink, setComlink] = useState<ChannelInstance<LoaderControllerMsg, LoaderNodeMsg>>()\n const [liveQueries, liveQueriesDispatch] = useLiveQueries()\n\n const projectId = useProjectId()\n const dataset = useDataset()\n\n useEffect((): (() => void) => {\n if (controller) {\n const nextComlink = controller.createChannel<LoaderControllerMsg, LoaderNodeMsg>(\n {\n name: 'presentation',\n connectTo: 'loaders',\n heartbeat: true,\n },\n createConnectionMachine<LoaderControllerMsg, LoaderNodeMsg>().provide({\n actors: createCompatibilityActors<LoaderControllerMsg>(),\n }),\n )\n setComlink(nextComlink)\n\n nextComlink.onStatus(onLoadersConnection)\n\n nextComlink.on('loader/documents', (data) => {\n if (data.projectId === projectId && data.dataset === dataset) {\n onDocumentsOnPage(\n 'loaders',\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n data.perspective as unknown as any,\n data.documents,\n )\n }\n })\n\n nextComlink.on('loader/query-listen', (data) => {\n if (data.projectId === projectId && data.dataset === dataset) {\n if (\n typeof data.heartbeat === 'number' &&\n data.heartbeat < MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL\n ) {\n throw new Error(\n `Loader query listen heartbeat interval must be at least ${MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL}ms`,\n )\n }\n liveQueriesDispatch({\n type: 'query-listen',\n payload: {\n perspective: data.perspective,\n query: data.query,\n params: data.params,\n heartbeat: data.heartbeat ?? false,\n },\n })\n }\n })\n\n return nextComlink.start()\n }\n return () => undefined\n }, [controller, dataset, liveQueriesDispatch, onDocumentsOnPage, onLoadersConnection, projectId])\n\n const studioClient = useClient({apiVersion: API_VERSION})\n const client = useMemo(\n () =>\n studioClient.withConfig({\n resultSourceMap: 'withKeyArraySelector',\n }),\n [studioClient],\n )\n useEffect(() => {\n if (comlink) {\n comlink.post('loader/perspective', {\n projectId,\n dataset,\n perspective: activePerspective,\n })\n }\n }, [comlink, activePerspective, projectId, dataset])\n\n /**\n * Defer the liveDocument to avoid unnecessary rerenders on rapid edits\n */\n const liveDocument = useDeferredValue(props.liveDocument)\n\n const liveEvents = useLiveEvents(client)\n\n return (\n <>\n {[...liveQueries.entries()].map(([key, {query, params, perspective}]) => (\n <QuerySubscription\n key={`${liveEvents.resets}:${key}`}\n projectId={projectId}\n dataset={dataset}\n perspective={perspective}\n query={query}\n params={params}\n comlink={comlink}\n client={client}\n liveDocument={liveDocument}\n liveEventsMessages={liveEvents.messages}\n />\n ))}\n </>\n )\n}\n\ninterface SharedProps {\n /**\n * The Sanity client to use for fetching data and listening to mutations.\n */\n client: SanityClient\n}\n\ninterface QuerySubscriptionProps\n extends Pick<UseQuerySubscriptionProps, 'client' | 'liveDocument' | 'liveEventsMessages'> {\n projectId: string\n dataset: string\n perspective: ClientPerspective\n query: string\n params: QueryParams\n comlink: LoaderConnection | undefined\n}\nfunction QuerySubscriptionComponent(props: QuerySubscriptionProps) {\n const {\n projectId,\n dataset,\n perspective,\n query,\n client,\n liveDocument,\n params,\n comlink,\n liveEventsMessages,\n } = props\n\n const {\n result,\n resultSourceMap,\n syncTags: tags,\n } = useQuerySubscription({\n client,\n liveDocument,\n params,\n perspective,\n query,\n liveEventsMessages,\n }) || {}\n\n /* eslint-disable @typescript-eslint/no-shadow,max-params */\n const handleQueryChange = useEffectEvent(\n (\n comlink: LoaderConnection | undefined,\n perspective: ClientPerspective,\n query: string,\n params: QueryParams,\n result: unknown,\n resultSourceMap: ContentSourceMap | undefined,\n tags: `s1:${string}`[] | undefined,\n ) => {\n comlink?.post('loader/query-change', {\n projectId,\n dataset,\n perspective,\n query,\n params,\n result,\n resultSourceMap,\n tags,\n })\n },\n )\n /* eslint-enable @typescript-eslint/no-shadow,max-params */\n\n useEffect(() => {\n if (resultSourceMap) {\n handleQueryChange(comlink, perspective, query, params, result, resultSourceMap, tags)\n }\n return undefined\n }, [comlink, handleQueryChange, params, perspective, query, result, resultSourceMap, tags])\n\n return null\n}\nconst QuerySubscription = memo(QuerySubscriptionComponent)\nQuerySubscription.displayName = 'Memo(QuerySubscription)'\n\ninterface UseQuerySubscriptionProps extends Required<Pick<SharedProps, 'client'>> {\n liveDocument: Partial<SanityDocument> | null | undefined\n query: string\n params: QueryParams\n perspective: ClientPerspective\n liveEventsMessages: LiveEventMessage[]\n}\nfunction useQuerySubscription(props: UseQuerySubscriptionProps) {\n const {liveDocument, client, query, params, perspective, liveEventsMessages} = props\n const [result, setResult] = useState<unknown>(null)\n const [resultSourceMap, setResultSourceMap] = useState<ContentSourceMap | null | undefined>(null)\n const [syncTags, setSyncTags] = useState<SyncTag[] | undefined>(undefined)\n const [skipEventIds] = useState(() => new Set(liveEventsMessages.map((msg) => msg.id)))\n const recentLiveEvents = liveEventsMessages.filter((msg) => !skipEventIds.has(msg.id))\n const lastLiveEvent = recentLiveEvents.findLast((msg) =>\n msg.tags.some((tag) => syncTags?.includes(tag)),\n )\n const lastLiveEventId = lastLiveEvent?.id\n\n // Make sure any async errors bubble up to the nearest error boundary\n const [error, setError] = useState<unknown>(null)\n if (error) throw error\n\n /* eslint-disable max-nested-callbacks */\n useEffect(() => {\n const controller = new AbortController()\n\n client\n .fetch(query, params, {\n lastLiveEventId,\n tag: 'presentation-loader',\n signal: controller.signal,\n perspective,\n filterResponse: false,\n returnQuery: false,\n })\n .then((response) => {\n startTransition(() => {\n // eslint-disable-next-line max-nested-callbacks\n setResult((prev: unknown) => (isEqual(prev, response.result) ? prev : response.result))\n setResultSourceMap((prev) =>\n isEqual(prev, response.resultSourceMap) ? prev : response.resultSourceMap,\n )\n setSyncTags((prev) => (isEqual(prev, response.syncTags) ? prev : response.syncTags))\n })\n })\n .catch((err) => {\n if (typeof err !== 'object' || err?.name !== 'AbortError') {\n setError(err)\n }\n })\n\n return () => {\n controller.abort()\n }\n }, [client, lastLiveEventId, params, perspective, query])\n /* eslint-enable max-nested-callbacks */\n\n return useMemo(() => {\n if (liveDocument && resultSourceMap) {\n return {\n result: turboChargeResultIfSourceMap(liveDocument, result, perspective, resultSourceMap),\n resultSourceMap,\n syncTags,\n }\n }\n return {result, resultSourceMap, syncTags}\n }, [liveDocument, perspective, result, resultSourceMap, syncTags])\n}\n\nexport function turboChargeResultIfSourceMap<T = unknown>(\n liveDocument: Partial<SanityDocument> | null | undefined,\n result: T,\n perspective: ClientPerspective,\n resultSourceMap?: ContentSourceMap,\n): T {\n if (perspective === 'raw') {\n throw new Error('turboChargeResultIfSourceMap does not support raw perspective')\n }\n return applySourceDocuments(\n result,\n resultSourceMap,\n (sourceDocument) => {\n // If there's a displayed document, always prefer it\n if (\n // If _projectId is set, it's a cross dataset reference and we should skip it\n !sourceDocument._projectId &&\n liveDocument?._id &&\n getPublishedId(liveDocument._id) === getPublishedId(sourceDocument._id)\n ) {\n if (typeof liveDocument._id === 'string' && typeof sourceDocument._type === 'string') {\n return liveDocument as unknown as Required<Pick<SanityDocument, '_id' | '_type'>>\n }\n return {\n ...liveDocument,\n _id: liveDocument._id || sourceDocument._id,\n _type: liveDocument._type || sourceDocument._type,\n }\n }\n return null\n },\n mapChangedValue,\n perspective,\n )\n}\n"],"names":["reducer","state","event","type","messages","resets","Error","cause","initialState","useLiveEvents","client","$","_c","dispatch","useReducer","error","setError","useState","t0","t1","live","subscription","events","includeDrafts","tag","subscribe","next","err","unsubscribe","useEffect","useDeferredValue","mapChangedValue","changedValue","previousValue","Array","isArray","length","some","node","isPortableTextBlock","toPlainText","getQueryCacheKey","perspective","query","params","JSON","stringify","gc","queries","size","now","Date","from","heartbeats","values","entry","heartbeat","receivedAt","nextHeartbeats","Map","nextQueries","key","entries","set","get","queryListen","payload","data","has","isEqual","action","useLiveQueries","Symbol","for","interval","setInterval","LOADER_QUERY_GC_INTERVAL","clearInterval","t2","LiveQueries","props","controller","activePerspective","onLoadersConnection","onDocumentsOnPage","comlink","setComlink","liveQueries","liveQueriesDispatch","projectId","useProjectId","dataset","useDataset","nextComlink","createChannel","name","connectTo","createConnectionMachine","provide","actors","createCompatibilityActors","onStatus","on","documents","data_0","MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL","start","_temp","apiVersion","API_VERSION","studioClient","useClient","t3","t4","withConfig","resultSourceMap","t5","t6","post","liveDocument","liveEvents","t7","t8","t9","map","t10","t11","QuerySubscriptionComponent","liveEventsMessages","result","syncTags","tags","useQuerySubscription","comlink_0","perspective_0","query_0","params_0","result_0","resultSourceMap_0","tags_0","handleQueryChange","useEffectEvent","QuerySubscription","memo","displayName","setResult","setResultSourceMap","setSyncTags","undefined","Set","_temp2","skipEventIds","msg_0","msg","id","recentLiveEvents","filter","msg_1","includes","findLast","lastLiveEventId","AbortController","fetch","signal","filterResponse","returnQuery","then","response","startTransition","prev","prev_0","prev_1","catch","abort","turboChargeResultIfSourceMap","bb0","applySourceDocuments","sourceDocument","_projectId","_id","getPublishedId","_type"],"mappings":";;;;;;AAiBgBA,SAAAA,UAAQC,OAAcC,OAAyB;AAC7D,UAAQA,MAAMC,MAAI;AAAA,IAChB,KAAK;AACI,aAAA;AAAA,QACL,GAAGF;AAAAA,QACHG,UAAU,CAAC,GAAGH,MAAMG,UAAUF,KAAK;AAAA,MACrC;AAAA,IACF,KAAK;AAAA,IACL,KAAK;AACI,aAAA;AAAA,QACL,GAAGD;AAAAA,QACHG,UAAU,CAAE;AAAA,QACZC,QAAQJ,MAAMI,SAAS;AAAA,MACzB;AAAA,IACF,KAAK;AAEIJ,aAAAA;AAAAA,IACT;AACE,YAAMK,MACJ;AAAA,MAEGJ,MAAcC,IAAI,IAErB;AAAA,QAACI,OAAOL;AAAAA,MAAAA,CACV;AAAA,EAAA;AAEN;AAEO,MAAMM,iBAAsB;AAAA,EACjCJ,UAAU,CAAE;AAAA,EACZC,QAAQ;AACV;AAEO,SAAAI,cAAAC,QAAA;AAAA,QAAAC,IAAAC,qBAAAA,EAAA,CAAA,GACLX,CAAAA,OAAAY,QAAA,IAA0BC,MAAAA,WAAAd,WAAAQ,cAAgC,GAC1D,CAAAO,OAAAC,QAAA,IAA0BC,mBAAsB;AAAC,MAC7CF,UAAc;AAEVA,UAAAA;AAAK,MAAAG,IAAAC;AAAA,SAAAR,EAAA,CAAA,MAAAD,OAAAU,QAGHF,KAAAA,MAAA;AACRG,UAAAA,eAAqBX,OAAMU,KAAAE,OAAA;AAAA,MAAAC,eAAA;AAAA,MAAAC,KACU;AAAA,IAAsB,CAAA,EAACC,UAAA;AAAA,MAAAC,MAElDb;AAAAA,MAAQE,OAAAY,SAEZX,SACEW,eAAGrB,QACCqB,MAAGrB,IAAAA,MACO,qCAAmC;AAAA,QAAAC,OAAUoB;AAAAA,MAAAA,CAC7D,CAAA;AAAA,IAAA,CACH;AAAC,WAAA,MACSN,aAAYO,YAAa;AAAA,EACrCT,GAAAA,KAAA,CAACT,OAAMU,IAAA,GAAMT,EAAA,CAAA,IAAAD,OAAAU,MAAAT,OAAAO,IAAAP,OAAAQ,OAAAD,KAAAP,EAAA,CAAA,GAAAQ,KAAAR,EAAA,CAAA,IAbhBkB,MAAUX,UAAAA,IAaPC,EAAa,GAETW,MAAAA,iBAAiB7B,KAAK;AAAC;AC/DnB8B,MAAAA,kBAAsDA,CACjEC,cACA;AAAA,EAACC;AAAa,MACX;AACC,MAAA,OAAOA,iBAAkB,UAAU;AACrC,QAAI,OAAOD,gBAAiB;AAE1B,aAAO,GAAGA,YAAY;AAGpBE,QAAAA,MAAMC,QAAQH,YAAY,GAAG;AAC/B,UAAIA,aAAaI,WAAW;AAEnB,eAAA;AAGLJ,UAAAA,aAAaK,KAAMC,CAAS,SAAA,OAAOA,QAAS,YAAYC,4BAAoBD,IAAI,CAAC;AACnF,eAAOE,MAAAA,YAAYR,YAAY;AAAA,IAAA;AAAA,EAEnC;AAGKA,SAAAA;AACT;AASgBS,SAAAA,iBACdC,aACAC,OACAC,QACe;AACR,SAAA,GAAGF,WAAW,IAAIC,KAAK,IAAIE,KAAKC,UAAUF,MAAM,CAAC;AAC1D;ACHA,SAASG,GAAG9C,OAAqB;AAC3BA,MAAAA,MAAM+C,QAAQC,OAAO;AAChBhD,WAAAA;AAGHiD,QAAAA,MAAMC,KAAKD,IAAI;AAIrB,MAAI,CAHkBhB,MAAMkB,KAAKnD,MAAMoD,WAAWC,QAAQ,EAAEjB,KACzDkB,CAAAA,UAAUA,MAAMC,cAAc,MAASN,MAAMK,MAAME,aAAaF,MAAMC,SACzE;AAESvD,WAAAA;AAET,QAAMyD,iBAAqBC,oBAAAA,IACrBC,GAAAA,kCAAkBD,IAAI;AAC5B,aAAW,CAACE,KAAKN,KAAK,KAAKtD,MAAMoD,WAAWS,QAAQ;AAC9CP,UAAMC,cAAc,MAASN,MAAMK,MAAME,aAAaF,MAAMC,cAGhEE,eAAeK,IAAIF,KAAKN,KAAK,GAC7BK,YAAYG,IAAIF,KAAK5D,MAAM+C,QAAQgB,IAAIH,GAAG,CAAC;AAGtC,SAAA;AAAA,IAAC,GAAG5D;AAAAA,IAAO+C,SAASY;AAAAA,IAAaP,YAAYK;AAAAA,EAAc;AACpE;AACA,SAASO,YAAYhE,OAAc;AAAA,EAACiE;AAA0B,GAAU;AAChEL,QAAAA,MAAMpB,iBAAiByB,QAAQxB,aAAawB,QAAQvB,OAAOuB,QAAQtB,MAAM,GACzEuB,OAAO;AAAA,IAACxB,OAAOuB,QAAQvB;AAAAA,IAAOC,QAAQsB,QAAQtB;AAAAA,IAAQF,aAAawB,QAAQxB;AAAAA,EAE3EgB,GAAAA,iBAAiB,IAAIC,IAAI1D,MAAMoD,UAAU;AAC/CK,iBAAeK,IAAIF,KAAK;AAAA,IACtBJ,YAAYN,KAAKD,IAAI;AAAA,IACrBM,WAAWU,QAAQV;AAAAA,EAAAA,CACpB;AAED,MAAII,cAAc3D,MAAM+C;AAOpB,UAAA,CAAC/C,MAAM+C,QAAQoB,IAAIP,GAAG,KAAK,CAACQ,yBAAQpE,MAAM+C,QAAQgB,IAAIH,GAAG,GAAGM,IAAI,OAClEP,cAAc,IAAID,IAAI1D,MAAM+C,OAAO,GACnCY,YAAYG,IAAIF,KAAKM,IAAI,IAGpB;AAAA,IAACd,YAAYK;AAAAA,IAAgBV,SAASY;AAAAA,EAAW;AAC1D;AAEgB5D,SAAAA,QAAQC,OAAcqE,QAAuB;AAC3D,UAAQA,OAAOnE,MAAI;AAAA,IACjB,KAAK;AACI8D,aAAAA,YAAYhE,OAAOqE,MAAM;AAAA,IAClC,KAAK;AACH,aAAOvB,GAAG9C,KAAK;AAAA,IACjB;AACE,YAAMK,MACJ;AAAA,MAEGgE,OAAenE,IAAI,IAEtB;AAAA,QAACI,OAAO+D;AAAAA,MAAAA,CACV;AAAA,EAAA;AAEN;AAEO,MAAM9D,eAAsB;AAAA,EACjCwC,6BAAaW,IAAI;AAAA,EACjBN,gCAAgBM,IAAI;AACtB;AAEO,SAAAY,iBAAA;AAAA5D,QAAAA,IAAAC,uBAAA,CAAA,GACLX,CAAAA,OAAAY,QAAA,IAA0BC,MAAAA,WAAAd,SAAAQ,YAAgC;AAAC,MAAAU,IAAAC;AAAAR,IAAA,CAAA,MAAA6D,OAAAC,IAAA,2BAAA,KAEjDvD,KAAAA,MAAA;AACRwD,UAAAA,WAAiBC,YAAA,MAAkB9D,SAAQ;AAAA,MAAAV,MAAQ;AAAA,IAAK,CAAA,GAACyE,aAAAA,wBAA0B;AACtEC,WAAAA,MAAAA,cAAcH,QAAQ;AAAA,EAAA,GAClCvD,KAAA,CAAA,GAAER,OAAAO,IAAAP,OAAAQ,OAAAD,KAAAP,EAAA,CAAA,GAAAQ,KAAAR,EAAA,CAAA,IAHLkB,MAAAA,UAAUX,IAGPC,EAAE;AAEL6B,QAAAA,UAAgBlB,MAAAA,iBAAiB7B,MAAK+C,OAAQ;AAAC8B,MAAAA;AAAAnE,SAAAA,SAAAqC,WACxC8B,KAAA,CAAC9B,SAASnC,QAAQ,GAACF,OAAAqC,SAAArC,OAAAmE,MAAAA,KAAAnE,EAAA,CAAA,GAAnBmE;AAAmB;AClF5B,SAAeC,YAAAC,OAAA;AAAArE,QAAAA,IAAAC,uBAAA,EAAA,GACb;AAAA,IAAAqE;AAAAA,IAAAvC,aAAAwC;AAAAA,IAAAC;AAAAA,IAAAC;AAAAA,EAAAA,IAA6FJ,OAE7F,CAAAK,WAAAC,UAAA,IAA8BrE,MAAAA,SAC9B,GAAA,CAAAsE,aAAAC,mBAAA,IAA2CjB,eAAe,GAE1DkB,YAAkBC,OAAAA,aAAa,GAC/BC,UAAgBC,kBAAW;AAAC,MAAA1E,IAAAC;AAAAR,WAAAsE,cAAAtE,EAAAgF,CAAAA,MAAAA,WAAAhF,EAAA6E,CAAAA,MAAAA,uBAAA7E,EAAA,CAAA,MAAAyE,qBAAAzE,SAAAwE,uBAAAxE,EAAA,CAAA,MAAA8E,aAElBvE,KAAAA,MAAA;AAAA,QACJ+D,YAAU;AACZY,YAAAA,cAAoBZ,WAAUa,cAAA;AAAA,QAAAC,MAEpB;AAAA,QAAcC,WACT;AAAA,QAASxC,WAAA;AAAA,MAAA,GAGtByC,QAAAA,wBAA4D,EAACC,QAAA;AAAA,QAAAC,QACnDC,oBAA+C,0BAAA;AAAA,MAAA,CACxD,CACH;AACWP,aAAAA,WAAAA,WAAW,GAEtBA,YAAWQ,SAAUlB,mBAAmB,GAExCU,YAAWS,GAAI,oBAAkBnC,CAAA,SAAA;AAC3BA,aAAIsB,cAAeA,aAAatB,KAAIwB,YAAaA,WACnDP,kBACE,WAEAjB,KAAIzB,aACJyB,KAAIoC,SACN;AAAA,MAEH,CAAA,GAEDV,YAAWS,GAAI,uBAAqBE,CAAA,WAAA;AAAA,YAC9BrC,OAAIsB,cAAeA,aAAatB,OAAIwB,YAAaA,SAAO;AAAA,cAExD,OAAOxB,OAAIX,aAAe,YAC1BW,OAAIX,YAAAiD,aAAAA;AAAuD,kBAAA,IAAAnG,MAGzD,2DAAAmG,aAAA,0CAAA,IAAyG;AAG1F,8BAAA;AAAA,YAAAtG,MACX;AAAA,YAAc+D,SAAA;AAAA,cAAAxB,aAELyB,OAAIzB;AAAAA,cAAAC,OACVwB,OAAIxB;AAAAA,cAAAC,QACHuB,OAAIvB;AAAAA,cAAAY,WACDW,OAAIX,aAAA;AAAA,YAAA;AAAA,UAAmB,CAErC;AAAA,QAAA;AAAA,MAAC,CAEL,GAEMqC,YAAWa,MAAO;AAAA,IAAA;AAACC,WAAAA;AAAAA,EAAA,GAG3BxF,KAAA,CAAC8D,YAAYU,SAASH,qBAAqBJ,mBAAmBD,qBAAqBM,SAAS,GAAC9E,OAAAsE,YAAAtE,OAAAgF,SAAAhF,OAAA6E,qBAAA7E,OAAAyE,mBAAAzE,OAAAwE,qBAAAxE,OAAA8E,WAAA9E,OAAAO,IAAAP,OAAAQ,OAAAD,KAAAP,EAAA,CAAA,GAAAQ,KAAAR,EAAA,CAAA,IApDhGkB,gBAAUX,IAoDPC,EAA6F;AAAC2D,MAAAA;AAAAnE,IAAA,CAAA,MAAA6D,OAAAC,IAAA,2BAAA,KAElEK,KAAA;AAAA,IAAA8B,YAAAC,aAAAA;AAAAA,EAAAA,GAAyBlG,OAAAmE,MAAAA,KAAAnE,EAAA,CAAA;AAAxDmG,QAAAA,eAAqBC,iBAAUjC,EAAyB;AAAC,MAAAkC,IAAAC;AAAAtG,WAAAmG,gBAGrDG,KAAAH,aAAYI,WAAA;AAAA,IAAAC,iBACO;AAAA,EAClB,CAAA,GAACxG,OAAAmG,cAAAnG,QAAAsG,MAAAA,KAAAtG,EAAA,EAAA,GAAAqG,KAFFC;AAFJ,QAAAvG,SAAesG;AAMd,MAAAI,IAAAC;AAAA1G,IAAA,EAAA,MAAAuE,qBAAAvE,EAAA0E,EAAAA,MAAAA,aAAA1E,EAAAgF,EAAAA,MAAAA,WAAAhF,UAAA8E,aACS2B,KAAAA,MAAA;AACJ/B,iBACFA,UAAOiC,KAAM,sBAAoB;AAAA,MAAA7B;AAAAA,MAAAE;AAAAA,MAAAjD,aAGlBwC;AAAAA,IAAAA,CACd;AAAA,EAAA,GAEFmC,MAAChC,WAASH,mBAAmBO,WAAWE,OAAO,GAAChF,QAAAuE,mBAAAvE,QAAA0E,WAAA1E,QAAAgF,SAAAhF,QAAA8E,WAAA9E,QAAAyG,IAAAzG,QAAA0G,OAAAD,KAAAzG,EAAA,EAAA,GAAA0G,KAAA1G,EAAA,EAAA,IARnDkB,MAAAA,UAAUuF,IAQPC,EAAgD;AAKnD,QAAAE,eAAqBzF,MAAAA,iBAAiBkD,MAAKuC,YAAa,GAExDC,aAAmB/G,cAAcC,MAAM;AAAC+G,MAAAA;AAAA9G,YAAA4E,eAI/BkC,KAAAlC,YAAWzB,WAAUnD,QAAA4E,aAAA5E,QAAA8G,MAAAA,KAAA9G,EAAA,EAAA;AAAA+G,MAAAA;AAAA/G,YAAA8G,MAAzBC,SAAID,EAAqB,GAAC9G,QAAA8G,IAAA9G,QAAA+G,MAAAA,KAAA/G,EAAA,EAAA;AAAAgH,MAAAA;AAAA,SAAAhH,EAAA,EAAA,MAAAD,UAAAC,EAAA0E,EAAAA,MAAAA,aAAA1E,UAAAgF,WAAAhF,EAAA,EAAA,MAAA4G,gBAAA5G,EAAA6G,EAAAA,MAAAA,WAAApH,YAAAO,UAAA6G,WAAAnH,UAAAM,EAAA8E,EAAAA,MAAAA,aAAA9E,UAAA+G,MAD7BC,KACGD,2BAAAA,IAAAA,qBAAAA,EAAAA,UAAAA,GAA0BE,IAAAC,CAAA,QAAA;AAAM,UAAA,CAAAhE,KAAAiE,GAAA,IAAAD,KAAM;AAAA,MAAAlF;AAAAA,MAAAC;AAAAA,MAAAF;AAAAA,IAAAA,IAAAoF;AAA4B,0CAChE,mBAEYrC,EAAAA,WACFE,SACIjD,aACNC,OACCC,QACCyC,SAAAA,WACD3E,QACM6G,cACM,oBAAAC,WAAUpH,SATzB,GAAA,GAAGoH,WAAUnH,MAAA,IAAWwD,GAAG,EAUhC;AAAA,EAAA,CACH,EAAC,CAAA,GACDlD,QAAAD,QAAAC,QAAA0E,WAAA1E,QAAAgF,SAAAhF,QAAA4G,cAAA5G,EAAA,EAAA,IAAA6G,WAAApH,UAAAO,EAAA,EAAA,IAAA6G,WAAAnH,QAAAM,QAAA8E,WAAA9E,QAAA+G,IAAA/G,QAAAgH,MAAAA,KAAAhH,EAAA,EAAA,GAfHgH;AAeG;AAxGQ,SAAAhB,QAAA;AAAA;AA4Hf,SAAAoB,2BAAA/C,OAAA;AAAArE,QAAAA,IAAAC,uBAAA,EAAA,GACE;AAAA,IAAA6E;AAAAA,IAAAE;AAAAA,IAAAjD;AAAAA,IAAAC;AAAAA,IAAAjC;AAAAA,IAAA6G;AAAAA,IAAA3E;AAAAA,IAAAyC,SAAAA;AAAAA,IAAA2C;AAAAA,MAUIhD,OAEJ;AAAA,IAAAiD;AAAAA,IAAAd;AAAAA,IAAAe,UAAAC;AAAAA,MAIIC,qBAAA;AAAA,IAAA1H;AAAAA,IAAA6G;AAAAA,IAAA3E;AAAAA,IAAAF;AAAAA,IAAAC;AAAAA,IAAAqF;AAAAA,EAOH,CAAA,KAAO,CAAA;AAAA9G,MAAAA;AAAAP,IAAAgF,CAAAA,MAAAA,WAAAhF,SAAA8E,aAINvE,KAAAA,CAAAmH,WAAAC,eAAAC,SAAAC,UAAAC,UAAAC,mBAAAC,WAAA;AASEtD,eAAOiC,KAAO,uBAAqB;AAAA,MAAA7B;AAAAA,MAAAE;AAAAA,MAAAjD,aAGjCA;AAAAA,MAAWC,OACXA;AAAAA,MAAKC,QACLA;AAAAA,MAAMqF,QACNA;AAAAA,MAAMd,iBACNA;AAAAA,MAAegB,MACfA;AAAAA,IAAAA,CAAI;AAAA,EAEPxH,GAAAA,OAAAgF,SAAAhF,OAAA8E,WAAA9E,OAAAO,MAAAA,KAAAP,EAAA,CAAA;AApBHiI,QAAAA,oBAA0BC,8BACxB3H,EAoBF;AAAC,MAAAC,IAAA2D;AAAA,SAAAnE,EAAA,CAAA,MAAA0E,YAAA1E,EAAA,CAAA,MAAAiI,qBAAAjI,EAAA,CAAA,MAAAiC,UAAAjC,EAAA+B,CAAAA,MAAAA,eAAA/B,EAAAgC,CAAAA,MAAAA,SAAAhC,EAAAsH,CAAAA,MAAAA,UAAAtH,EAAAwG,CAAAA,MAAAA,mBAAAxG,UAAAwH,QAGShH,KAAAA,MAAA;AACJgG,uBACFyB,kBAAkBvD,UAAS3C,aAAaC,OAAOC,QAAQqF,QAAQd,iBAAiBgB,IAAI;AAAA,EAGrFrD,GAAAA,KAACO,CAAAA,UAASuD,mBAAmBhG,QAAQF,aAAaC,OAAOsF,QAAQd,iBAAiBgB,IAAI,GAACxH,OAAA0E,UAAA1E,OAAAiI,mBAAAjI,OAAAiC,QAAAjC,OAAA+B,aAAA/B,OAAAgC,OAAAhC,OAAAsH,QAAAtH,OAAAwG,iBAAAxG,QAAAwH,MAAAxH,QAAAQ,IAAAR,QAAAmE,OAAA3D,KAAAR,EAAA,EAAA,GAAAmE,KAAAnE,EAAA,EAAA,IAL1FkB,MAAAA,UAAUV,IAKP2D,EAAuF,GAAC;AAAA;AAI7F,MAAMgE,oBAAoBC,WAAKhB,0BAA0B;AACzDe,kBAAkBE,cAAc;AAShC,SAAAZ,qBAAApD,OAAA;AAAArE,QAAAA,IAAAC,uBAAA,EAAA,GACE;AAAA,IAAA2G;AAAAA,IAAA7G;AAAAA,IAAAiC;AAAAA,IAAAC;AAAAA,IAAAF;AAAAA,IAAAsF;AAAAA,EAAAA,IAA+EhD,OAC/E,CAAAiD,QAAAgB,SAAA,IAA4BhI,mBAAsB,GAClD,CAAAkG,iBAAA+B,kBAAA,IAA8CjI,MAAAA,aAAkD,GAChG,CAAAiH,UAAAiB,WAAA,IAAgClI,MAAAA,SAAAmI,MAAyC;AAAClI,MAAAA;AAAAP,WAAAqH,sBAC1C9G,KAAAA,MAAA,IAAAmI,IAAcrB,mBAAkBJ,IAAA0B,MAAoB,CAAC,GAAC3I,OAAAqH,oBAAArH,OAAAO,MAAAA,KAAAP,EAAA,CAAA;AAAtF,QAAA,CAAA4I,YAAA,IAAuBtI,MAAAA,SAASC,EAAsD;AAACC,MAAAA;AAAAR,MAAAA,EAAAqH,CAAAA,MAAAA,sBAAArH,SAAA4I,gBAAA5I,EAAA,CAAA,MAAAuH,UAAA;AAAApD,QAAAA;AAAAnE,aAAA4I,gBACpCzE,MAAA0E,CAAA,UAAA,CAAUD,aAAYnF,IAAKqF,MAAGC,EAAG,GAAC/I,OAAA4I,cAAA5I,OAAAmE,OAAAA,MAAAnE,EAAA,CAAA;AAArFgJ,UAAAA,mBAAyB3B,mBAAkB4B,OAAQ9E,GAAkC;AAACkC,QAAAA;AAAArG,aAAAuH,YACtClB,MAAA6C,CAC9CJ,UAAAA,MAAGtB,KAAA9F,KAAAb,CAAAA,QAAoB0G,UAAQ4B,SAAWtI,GAAG,CAAC,GAACb,OAAAuH,UAAAvH,OAAAqG,OAAAA,MAAArG,EAAA,CAAA,GAD3BQ,KAAAwI,iBAAgBI,SAAU/C,GAEhD,GAACrG,OAAAqH,oBAAArH,OAAA4I,cAAA5I,OAAAuH,UAAAvH,OAAAQ;AAAAA,EAAA;AAAAA,SAAAR,EAAA,CAAA;AACDqJ,QAAAA,kBAHsB7I,IAGeuI,IAGrC,CAAA3I,OAAAC,QAAA,IAA0BC,mBAAsB;AAC5CF,MAAAA;AAAaA,UAAAA;AAAK,MAAA+D,IAAAkC;AAAArG,IAAAD,EAAAA,MAAAA,UAAAC,EAAA,EAAA,MAAAqJ,mBAAArJ,EAAAiC,EAAAA,MAAAA,UAAAjC,EAAA,EAAA,MAAA+B,eAAA/B,UAAAgC,SAGZmC,KAAAA,MAAA;AACRG,UAAAA,iBAAAgF,gBAAA;AAEMC,WAAAA,OAAAA,MACGvH,OAAOC,QAAM;AAAA,MAAAoH;AAAAA,MAAAxI,KAEb;AAAA,MAAqB2I,QAClBlF,WAAUkF;AAAAA,MAAAzH;AAAAA,MAAA0H,gBAAA;AAAA,MAAAC,aAAA;AAAA,IAAA,CAInB,EAACC,KAAAC,CAAA,aAAA;AAEAC,YAAAA,gBAAA,MAAA;AAEEvB,kBAASwB,CAAqBpG,SAAAA,iBAAAA,QAAQoG,MAAMF,SAAQtC,MAAO,IAAIwC,OAAOF,SAAQtC,MAAQ,GACtFiB,mBAAkBwB,CAAAA,WAChBrG,yBAAQoG,QAAMF,SAAQpD,eAAgB,IAAIsD,SAAOF,SAAQpD,eAC3D,GACAgC,YAAWwB,CAAAA,WAAYtG,iBAAAA,QAAQoG,QAAMF,SAAQrC,QAAS,IAAIuC,SAAOF,SAAQrC,QAAU;AAAA,MAAA,CACpF;AAAA,IAAA,CACF,EAAC0C,MAAAjJ,CAAA,QAAA;AAAA,OAEI,OAAOA,OAAQ,YAAYA,KAAGoE,SAAW,iBAC3C/E,SAASW,GAAG;AAAA,IAEf,CAAA,GAAC,MAAA;AAGFsD,iBAAU4F,MAAO;AAAA,IAAC;AAAA,EAAA,GAEnB7D,KAAA,CAACtG,QAAQsJ,iBAAiBpH,QAAQF,aAAaC,KAAK,GAAChC,QAAAD,QAAAC,QAAAqJ,iBAAArJ,QAAAiC,QAAAjC,QAAA+B,aAAA/B,QAAAgC,OAAAhC,QAAAmE,IAAAnE,QAAAqG,OAAAlC,KAAAnE,EAAA,EAAA,GAAAqG,KAAArG,EAAA,EAAA,IA/BxDkB,MAAAA,UAAUiD,IA+BPkC,EAAqD;AAACC,MAAAA;AAAA,OAAA;AAAA,QAInDM,gBAAgBJ,iBAAe;AAAAC,UAAAA;AAAAzG,QAAA,EAAA,MAAA4G,gBAAA5G,EAAA+B,EAAAA,MAAAA,eAAA/B,EAAAsH,EAAAA,MAAAA,UAAAtH,UAAAwG,mBAEvBC,MAAA0D,6BAA6BvD,cAAcU,QAAQvF,aAAayE,eAAe,GAACxG,QAAA4G,cAAA5G,QAAA+B,aAAA/B,QAAAsH,QAAAtH,QAAAwG,iBAAAxG,QAAAyG,OAAAA,MAAAzG,EAAA,EAAA;AAAA0G,UAAAA;AAAA1G,QAAAwG,EAAAA,MAAAA,mBAAAxG,UAAAuH,YAAAvH,EAAA,EAAA,MAAAyG,OADnFC,KAAA;AAAA,QAAAY,QACGb;AAAAA,QAAgFD;AAAAA,QAAAe;AAAAA,MAAAA,GAGzFvH,QAAAwG,iBAAAxG,QAAAuH,UAAAvH,QAAAyG,KAAAzG,QAAA0G,MAAAA,KAAA1G,EAAA,EAAA,GAJDsG,KAAOI;AAIN0D,YAAAA;AAAAA,IAAAA;AAAA3D,QAAAA;AAAAzG,MAAAsH,EAAAA,MAAAA,UAAAtH,UAAAwG,mBAAAxG,EAAA,EAAA,MAAAuH,YAEId,KAAA;AAAA,MAAAa;AAAAA,MAAAd;AAAAA,MAAAe;AAAAA,IAAAA,GAAmCvH,QAAAsH,QAAAtH,QAAAwG,iBAAAxG,QAAAuH,UAAAvH,QAAAyG,MAAAA,KAAAzG,EAAA,EAAA,GAA1CsG,KAAOG;AAAAA,EAAAA;AARFH,SAAAA;AAS2D;AA5DpE,SAAAqC,OAAAG,KAAA;AAAA,SAKgFA,IAAGC;AAAA;AA0D5E,SAASoB,6BACdvD,cACAU,QACAvF,aACAyE,iBACG;AACH,MAAIzE,gBAAgB;AACZ,UAAA,IAAIpC,MAAM,+DAA+D;AAE1E0K,SAAAA,yBACL/C,QACAd,iBACC8D,CAAAA;AAAAA;AAAAA,IAIG,CAACA,eAAeC,cAChB3D,cAAc4D,OACdC,IAAAA,eAAe7D,aAAa4D,GAAG,MAAMC,mBAAeH,eAAeE,GAAG,IAElE,OAAO5D,aAAa4D,OAAQ,YAAY,OAAOF,eAAeI,SAAU,WACnE9D,eAEF;AAAA,MACL,GAAGA;AAAAA,MACH4D,KAAK5D,aAAa4D,OAAOF,eAAeE;AAAAA,MACxCE,OAAO9D,aAAa8D,SAASJ,eAAeI;AAAAA,IAAAA,IAGzC;AAAA,KAETtJ,iBACAW,WACF;AACF;;;"}