camox 0.68.0 → 0.69.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -26,7 +26,7 @@ const mirror = (message) => mirrors[message.store]?.send({
26
26
  * its cache follows the studio's (see `protocol.ts`). The studio's questions are answered from
27
27
  * `camoxApp`, the draft's code; without it, none can be.
28
28
  */
29
- function connectToStudio(handle, { queryClient, studioCache, draftScope, camoxApp }) {
29
+ function connectToStudio(handle, { queryClient, studioCache, draftScope, camoxApp, prepareFrame }) {
30
30
  let welcomed = false;
31
31
  let frames = [];
32
32
  const listeners = /* @__PURE__ */ new Set();
@@ -109,6 +109,14 @@ function connectToStudio(handle, { queryClient, studioCache, draftScope, camoxAp
109
109
  return;
110
110
  case "ask": {
111
111
  const { askId, question } = message;
112
+ if (question.type === "prepareFrame") {
113
+ (prepareFrame?.(question) ?? Promise.resolve()).catch(() => {}).then(() => studio({
114
+ type: "answer",
115
+ askId,
116
+ value: null
117
+ }));
118
+ return;
119
+ }
112
120
  if (!camoxApp) {
113
121
  studio({
114
122
  type: "answer",
@@ -1,7 +1,8 @@
1
- import { DraftScopeContext, draftNamedBy } from "../../lib/draft-scope.js";
1
+ import { DraftScopeContext, ShownDraftContext, draftNamedBy } from "../../lib/draft-scope.js";
2
2
  import { PageAlternatesContext, ViewLocaleContext } from "../../lib/view-locale-context.js";
3
3
  import { NavigationProvider } from "../navigation/navigation.js";
4
4
  import { fetchRuntimeJson, getNavigationTarget } from "./navigationTarget.js";
5
+ import { SWITCH_WAIT_MS, ViewSwitchDeadlineContext, ViewSwitchesContext } from "../../lib/view-switch.js";
5
6
  import { reads } from "../../lib/studio-reads.js";
6
7
  import { createPrefetchCache, listenForLinkIntent } from "./linkPrefetch.js";
7
8
  import { PageViewportContext } from "./pageViewport.js";
@@ -13,7 +14,7 @@ import { createNavigationRequestTracker } from "./navigationRequest.js";
13
14
  import { createScrollRestoration } from "./scrollRestoration.js";
14
15
  import { c } from "react/compiler-runtime";
15
16
  import * as React from "react";
16
- import { jsx } from "react/jsx-runtime";
17
+ import { jsx, jsxs } from "react/jsx-runtime";
17
18
  import { hydrate } from "@tanstack/react-query";
18
19
  import { createHead, renderDOMHead } from "@unhead/react/client";
19
20
 
@@ -63,13 +64,24 @@ function prefetchKey(pathname, draft) {
63
64
  function PageNavigationProvider({ camoxApp, children, initialInput, queryClient }) {
64
65
  const draftScope = React.useContext(DraftScopeContext);
65
66
  if (!draftScope) throw new Error("PageNavigationProvider needs a DraftScopeContext provider");
66
- const [{ input, source, generation }, setLocation] = React.useState(() => {
67
+ const [{ input, source, switched, navigation }, setLocation] = React.useState(() => {
67
68
  draftScope.adopt(initialInput);
68
69
  return {
69
70
  input: initialInput,
70
- generation: 0
71
+ navigation: 0
71
72
  };
72
73
  });
74
+ const [preparers] = React.useState(() => /* @__PURE__ */ new Set());
75
+ const [commits] = React.useState(() => /* @__PURE__ */ new Map());
76
+ const navigations = React.useRef(0);
77
+ const lastShown = React.useRef(Promise.resolve());
78
+ const switches = React.useMemo(() => ({
79
+ prepare(preparer) {
80
+ preparers.add(preparer);
81
+ return () => void preparers.delete(preparer);
82
+ },
83
+ shown: () => lastShown.current
84
+ }), [preparers]);
73
85
  const current = React.useRef(initialInput);
74
86
  const [requests] = React.useState(createNavigationRequestTracker);
75
87
  const ownsWindow = initialInput.presentation !== "studio";
@@ -88,6 +100,20 @@ function PageNavigationProvider({ camoxApp, children, initialInput, queryClient
88
100
  }, [restoration]);
89
101
  const pendingAnnouncement = React.useRef(null);
90
102
  const announcer = React.useRef(null);
103
+ const prepareSwitch = React.useCallback((next) => {
104
+ const view = {
105
+ pathname: next.pathname,
106
+ ...next.derived && { derivedLayoutId: next.derived.layoutId },
107
+ draftId: next.draftId ?? null,
108
+ locale: next.locale
109
+ };
110
+ const deadline = Date.now() + SWITCH_WAIT_MS;
111
+ const prepared = Promise.all([...preparers].map((prepare) => Promise.resolve(prepare(view)).catch(() => {})));
112
+ return {
113
+ deadline,
114
+ ready: Promise.race([prepared.then(() => {}), new Promise((resolve) => setTimeout(resolve, SWITCH_WAIT_MS))])
115
+ };
116
+ }, [preparers]);
91
117
  const loadPage = React.useCallback(async (pathname, draft, signal) => {
92
118
  const response = await fetchRuntimeJson(draftScope, "/_camox/data", initialInput.runtimeBasePath, { path: pathname }, draft, signal);
93
119
  if (!response.ok) throw new Error(`Navigation failed: ${response.status}`);
@@ -106,6 +132,7 @@ function PageNavigationProvider({ camoxApp, children, initialInput, queryClient
106
132
  const { analytics } = initialInput;
107
133
  const navigate = React.useCallback(async ({ to, replace, source, draft, pop = false, refresh = false }) => {
108
134
  const request = requests.begin();
135
+ const id = ++navigations.current;
109
136
  const href = pop ? to : draftScope.hrefFor(to, {
110
137
  from: window.location.href,
111
138
  draft
@@ -122,12 +149,20 @@ function PageNavigationProvider({ camoxApp, children, initialInput, queryClient
122
149
  if (target.url.hash && viewport) position(viewport, "fragment", target.url.href);
123
150
  return;
124
151
  }
152
+ lastShown.current = new Promise((resolve) => commits.set(id, resolve));
153
+ const settle = () => {
154
+ for (const [waiting, resolve] of commits) {
155
+ if (waiting > id) continue;
156
+ commits.delete(waiting);
157
+ resolve();
158
+ }
159
+ };
125
160
  try {
126
161
  let next = current.current;
127
162
  const targetDraft = draftNamedBy(target.url.href);
128
163
  const fetched = target.pathname !== next.pathname || refresh || targetDraft !== draftNamedBy(next.href);
129
164
  if (fetched) next = await (!refresh && prefetched.take(prefetchKey(target.pathname, targetDraft)) || loadPage(target.pathname, targetDraft, request.signal));
130
- if (!request.isCurrent()) return;
165
+ if (!request.isCurrent()) return settle();
131
166
  const switching = (next.draftId ?? null) !== (current.current.draftId ?? null) || !sameLocale(next.locale, current.current.locale);
132
167
  const positions = restoration();
133
168
  if (!pop) {
@@ -145,6 +180,7 @@ function PageNavigationProvider({ camoxApp, children, initialInput, queryClient
145
180
  };
146
181
  pendingAnnouncement.current = fetched && !refresh ? next.pathname : null;
147
182
  if (fetched) draftScope.adopt(next);
183
+ const switched = switching ? prepareSwitch(next) : void 0;
148
184
  hydrate(queryClient, switching ? next.dehydratedState : preserveStableLayoutBlockCaches(next.dehydratedState, current.current.layoutIdentity, next.layoutIdentity));
149
185
  next = {
150
186
  ...next,
@@ -162,12 +198,14 @@ function PageNavigationProvider({ camoxApp, children, initialInput, queryClient
162
198
  renderDOMHead(manager.head);
163
199
  if (ownsWindow && analytics && next.pathname !== previous.pathname) sendPageView(analytics, window);
164
200
  if (ownsWindow) document.documentElement.lang = next.locale.tag;
165
- React.startTransition(() => setLocation((location) => ({
201
+ React.startTransition(() => setLocation({
166
202
  input: next,
167
203
  source: pop ? void 0 : source,
168
- generation: location.generation + (switching ? 1 : 0)
169
- })));
204
+ switched,
205
+ navigation: id
206
+ }));
170
207
  } catch {
208
+ settle();
171
209
  if (!request.isCurrent()) return;
172
210
  if (pop) window.location.reload();
173
211
  else if (replace) window.location.replace(target.url.href);
@@ -175,12 +213,14 @@ function PageNavigationProvider({ camoxApp, children, initialInput, queryClient
175
213
  }
176
214
  }, [
177
215
  analytics,
216
+ commits,
178
217
  draftScope,
179
218
  initialInput.runtimeBasePath,
180
219
  loadPage,
181
220
  ownsWindow,
182
221
  position,
183
222
  prefetched,
223
+ prepareSwitch,
184
224
  queryClient,
185
225
  requests,
186
226
  restoration
@@ -250,6 +290,21 @@ function PageNavigationProvider({ camoxApp, children, initialInput, queryClient
250
290
  prefetched.clear();
251
291
  };
252
292
  }, [draftScope, prefetched]);
293
+ React.useLayoutEffect(() => {
294
+ for (const [waiting, resolve] of commits) {
295
+ if (waiting > navigation) continue;
296
+ commits.delete(waiting);
297
+ resolve();
298
+ }
299
+ if (switched) setLocation((location) => ({
300
+ ...location,
301
+ switched: void 0
302
+ }));
303
+ }, [
304
+ commits,
305
+ navigation,
306
+ switched
307
+ ]);
253
308
  React.useLayoutEffect(() => {
254
309
  const intent = takeScroll(input.href);
255
310
  const viewport = scroll.current?.viewport();
@@ -310,13 +365,14 @@ function PageNavigationProvider({ camoxApp, children, initialInput, queryClient
310
365
  initialInput.runtimeBasePath,
311
366
  requests
312
367
  ]);
368
+ const hydrated = React.useSyncExternalStore(noSubscription, isClient, isServer);
313
369
  const url = new URL(input.href);
314
370
  const viewLocale = useSameJson({
315
371
  locale: input.locale,
316
372
  locales: input.locales
317
373
  });
318
374
  const alternates = useSameJson(input.alternates ?? null);
319
- return /* @__PURE__ */ jsx(NavigationProvider, {
375
+ return /* @__PURE__ */ jsxs(NavigationProvider, {
320
376
  location: {
321
377
  href: input.href,
322
378
  pathname: input.pathname,
@@ -325,18 +381,38 @@ function PageNavigationProvider({ camoxApp, children, initialInput, queryClient
325
381
  source
326
382
  },
327
383
  navigate,
328
- children: /* @__PURE__ */ jsx(ViewLocaleContext, {
329
- value: viewLocale,
330
- children: /* @__PURE__ */ jsx(PageAlternatesContext, {
331
- value: alternates,
332
- children: /* @__PURE__ */ jsx(PageViewportContext, {
333
- value: pageViewport,
334
- children: /* @__PURE__ */ jsx(React.Fragment, { children: children(input) }, generation)
384
+ children: [/* @__PURE__ */ jsx(ViewSwitchesContext, {
385
+ value: switches,
386
+ children: /* @__PURE__ */ jsx(ViewSwitchDeadlineContext, {
387
+ value: switched?.deadline ?? null,
388
+ children: /* @__PURE__ */ jsx(ShownDraftContext, {
389
+ value: input.draftId ?? null,
390
+ children: /* @__PURE__ */ jsx(ViewLocaleContext, {
391
+ value: viewLocale,
392
+ children: /* @__PURE__ */ jsx(PageAlternatesContext, {
393
+ value: alternates,
394
+ children: /* @__PURE__ */ jsx(PageViewportContext, {
395
+ value: pageViewport,
396
+ children: children(input)
397
+ })
398
+ })
399
+ })
335
400
  })
336
401
  })
337
- })
402
+ }), hydrated && /* @__PURE__ */ jsx(React.Suspense, {
403
+ fallback: null,
404
+ children: /* @__PURE__ */ jsx(SwitchGate, { ready: switched?.ready })
405
+ })]
338
406
  });
339
407
  }
408
+ const noSubscription = () => () => {};
409
+ const isClient = () => true;
410
+ const isServer = () => false;
411
+ /** Suspends the switch's render until the next view is ready. */
412
+ function SwitchGate({ ready }) {
413
+ if (ready) React.use(ready);
414
+ return null;
415
+ }
340
416
 
341
417
  //#endregion
342
418
  export { PageNavigationProvider };
@@ -1,5 +1,5 @@
1
1
  import { DraftScopeContext, createDraftScope, followUrl } from "../../lib/draft-scope.js";
2
- import { StudioCacheContext, createStudioCache } from "../../lib/studio-reads.js";
2
+ import { StudioCacheContext, createStudioCache, reads } from "../../lib/studio-reads.js";
3
3
  import { getDraftReadClient } from "../../lib/api-client.js";
4
4
  import { STUDIO_HANDLE_KEY } from "../renderer/protocol.js";
5
5
  import { CoreCamoxProvider } from "../provider/CoreCamoxProvider.js";
@@ -23,7 +23,8 @@ async function startRendererWithApp(camoxApp) {
23
23
  return;
24
24
  }
25
25
  const input = readHydrationData();
26
- if (!input.apiUrl || !input.authenticationUrl || !input.projectUuid) {
26
+ const { projectUuid, runtimeBasePath } = input;
27
+ if (!input.apiUrl || !input.authenticationUrl || !projectUuid) {
27
28
  console.error("Camox: the renderer document is missing its API or project.");
28
29
  return;
29
30
  }
@@ -44,7 +45,13 @@ async function startRendererWithApp(camoxApp) {
44
45
  queryClient,
45
46
  studioCache,
46
47
  draftScope,
47
- camoxApp
48
+ camoxApp,
49
+ prepareFrame: ({ pathname, derivedLayoutId, locale }) => Promise.all([studioCache.ensure(reads.canvasFrame({
50
+ projectUuid,
51
+ runtimeBasePath,
52
+ pathname,
53
+ ...derivedLayoutId && { derivedLayoutId }
54
+ }), { locale }), codeLoaded])
48
55
  });
49
56
  const container = document.createElement("div");
50
57
  document.body.append(container);
@@ -58,14 +65,14 @@ async function startRendererWithApp(camoxApp) {
58
65
  apiUrl: input.apiUrl,
59
66
  authenticationUrl: input.authenticationUrl,
60
67
  camoxApp,
61
- projectUuid: input.projectUuid,
68
+ projectUuid,
62
69
  initialAuthenticated: true,
63
70
  children: /* @__PURE__ */ jsx(CompleteBlockEditingRuntimeProvider, { children: /* @__PURE__ */ jsx(RendererApp, {
64
71
  connection,
65
72
  camoxApp,
66
73
  codeLoaded,
67
- projectUuid: input.projectUuid,
68
- runtimeBasePath: input.runtimeBasePath
74
+ projectUuid,
75
+ runtimeBasePath
69
76
  }) })
70
77
  })
71
78
  })
@@ -6,7 +6,8 @@ import { reads, useReadQuery } from "../../../lib/studio-reads.js";
6
6
  import { cn } from "../../../lib/utils.js";
7
7
  import { studioStore } from "../studioStore.js";
8
8
  import { draftLabel, plural, timeAgo } from "../draftLabel.js";
9
- import { DeleteDraftDialog, ReviewDraftSheet, useLeaveDraft } from "./ReviewDraftSheet.js";
9
+ import { useLeaveDraft, useSwitchView } from "../viewSwitch.js";
10
+ import { DeleteDraftDialog, ReviewDraftSheet } from "./ReviewDraftSheet.js";
10
11
  import { c } from "react/compiler-runtime";
11
12
  import * as React from "react";
12
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -97,12 +98,13 @@ function useDrafts() {
97
98
  * still names what the studio is viewing.
98
99
  */
99
100
  function DraftPicker(t0) {
100
- const $ = c(66);
101
+ const $ = c(68);
101
102
  const { disabled: t1 } = t0;
102
103
  const disabled = t1 === void 0 ? false : t1;
103
104
  const { draftScope, draftId, projectId, list, current } = useDrafts();
104
105
  const navigate = useNavigate();
105
106
  const leaveDraft = useLeaveDraft();
107
+ const switchView = useSwitchView();
106
108
  const review = useSelector(studioStore, _temp);
107
109
  const deleting = useSelector(studioStore, _temp2);
108
110
  let t2;
@@ -134,23 +136,30 @@ function DraftPicker(t0) {
134
136
  } else t5 = $[6];
135
137
  const drafts = t5;
136
138
  let t6;
137
- if ($[7] !== draftId || $[8] !== navigate) {
139
+ if ($[7] !== draftId || $[8] !== drafts || $[9] !== navigate || $[10] !== switchView) {
138
140
  t6 = (next) => {
139
141
  if (next === draftId) return;
140
- navigate({
142
+ const target = next ? drafts.find((draft) => draft.id === next) : void 0;
143
+ const label = next ? target ? draftLabel(target) : "the draft" : "Live";
144
+ switchView(() => navigate({
141
145
  to: window.location.href,
142
146
  draft: next
147
+ }), {
148
+ loading: `Switching to ${label}…`,
149
+ success: `You're now viewing ${label}.`
143
150
  });
144
151
  };
145
152
  $[7] = draftId;
146
- $[8] = navigate;
147
- $[9] = t6;
148
- } else t6 = $[9];
153
+ $[8] = drafts;
154
+ $[9] = navigate;
155
+ $[10] = switchView;
156
+ $[11] = t6;
157
+ } else t6 = $[11];
149
158
  const switchTo = t6;
150
159
  const t7 = !!projectId;
151
160
  const t8 = current?.name === null;
152
161
  let t9;
153
- if ($[10] !== draftId || $[11] !== drafts || $[12] !== switchTo || $[13] !== t7 || $[14] !== t8) {
162
+ if ($[12] !== draftId || $[13] !== drafts || $[14] !== switchTo || $[15] !== t7 || $[16] !== t8) {
154
163
  t9 = {
155
164
  enabled: t7,
156
165
  draftId,
@@ -158,65 +167,65 @@ function DraftPicker(t0) {
158
167
  drafts,
159
168
  switchTo
160
169
  };
161
- $[10] = draftId;
162
- $[11] = drafts;
163
- $[12] = switchTo;
164
- $[13] = t7;
165
- $[14] = t8;
166
- $[15] = t9;
167
- } else t9 = $[15];
170
+ $[12] = draftId;
171
+ $[13] = drafts;
172
+ $[14] = switchTo;
173
+ $[15] = t7;
174
+ $[16] = t8;
175
+ $[17] = t9;
176
+ } else t9 = $[17];
168
177
  useDraftsActions(t9);
169
178
  if (draftId && !current) return null;
170
179
  let t10;
171
- if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
180
+ if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
172
181
  t10 = /* @__PURE__ */ jsx(Button, {
173
182
  type: "button",
174
183
  variant: "ghost"
175
184
  });
176
- $[16] = t10;
177
- } else t10 = $[16];
185
+ $[18] = t10;
186
+ } else t10 = $[18];
178
187
  const t11 = draftId ? "bg-blue-500" : "bg-emerald-500";
179
188
  let t12;
180
- if ($[17] !== t11) {
189
+ if ($[19] !== t11) {
181
190
  t12 = cn("size-2 shrink-0 rounded-full", t11);
182
- $[17] = t11;
183
- $[18] = t12;
184
- } else t12 = $[18];
191
+ $[19] = t11;
192
+ $[20] = t12;
193
+ } else t12 = $[20];
185
194
  let t13;
186
- if ($[19] !== t12) {
195
+ if ($[21] !== t12) {
187
196
  t13 = /* @__PURE__ */ jsx("span", {
188
197
  "aria-hidden": true,
189
198
  className: t12
190
199
  });
191
- $[19] = t12;
192
- $[20] = t13;
193
- } else t13 = $[20];
200
+ $[21] = t12;
201
+ $[22] = t13;
202
+ } else t13 = $[22];
194
203
  let t14;
195
- if ($[21] !== current || $[22] !== draftId) {
204
+ if ($[23] !== current || $[24] !== draftId) {
196
205
  t14 = draftId ? draftLabel(current) : "Live";
197
- $[21] = current;
198
- $[22] = draftId;
199
- $[23] = t14;
200
- } else t14 = $[23];
206
+ $[23] = current;
207
+ $[24] = draftId;
208
+ $[25] = t14;
209
+ } else t14 = $[25];
201
210
  let t15;
202
- if ($[24] !== t14) {
211
+ if ($[26] !== t14) {
203
212
  t15 = /* @__PURE__ */ jsx("span", {
204
213
  className: "max-w-48 truncate",
205
214
  children: t14
206
215
  });
207
- $[24] = t14;
208
- $[25] = t15;
209
- } else t15 = $[25];
216
+ $[26] = t14;
217
+ $[27] = t15;
218
+ } else t15 = $[27];
210
219
  let t16;
211
- if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
220
+ if ($[28] === Symbol.for("react.memo_cache_sentinel")) {
212
221
  t16 = /* @__PURE__ */ jsx(ChevronsUpDown, {
213
222
  "aria-hidden": true,
214
223
  className: "size-4 opacity-50"
215
224
  });
216
- $[26] = t16;
217
- } else t16 = $[26];
225
+ $[28] = t16;
226
+ } else t16 = $[28];
218
227
  let t17;
219
- if ($[27] !== disabled || $[28] !== t13 || $[29] !== t15) {
228
+ if ($[29] !== disabled || $[30] !== t13 || $[31] !== t15) {
220
229
  t17 = /* @__PURE__ */ jsxs(DropdownMenuTrigger, {
221
230
  disabled,
222
231
  render: t10,
@@ -226,48 +235,48 @@ function DraftPicker(t0) {
226
235
  t16
227
236
  ]
228
237
  });
229
- $[27] = disabled;
230
- $[28] = t13;
231
- $[29] = t15;
232
- $[30] = t17;
233
- } else t17 = $[30];
238
+ $[29] = disabled;
239
+ $[30] = t13;
240
+ $[31] = t15;
241
+ $[32] = t17;
242
+ } else t17 = $[32];
234
243
  let t18;
235
- if ($[31] !== draftId) {
244
+ if ($[33] !== draftId) {
236
245
  t18 = !draftId && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsx(DropdownMenuLabel, {
237
246
  className: "text-muted-foreground font-normal",
238
247
  children: "Live is read-only. Your first edit starts a new draft."
239
248
  }) }), /* @__PURE__ */ jsx(DropdownMenuSeparator, {})] });
240
- $[31] = draftId;
241
- $[32] = t18;
242
- } else t18 = $[32];
249
+ $[33] = draftId;
250
+ $[34] = t18;
251
+ } else t18 = $[34];
243
252
  const t19 = draftId ?? LIVE;
244
253
  let t20;
245
- if ($[33] !== switchTo) {
254
+ if ($[35] !== switchTo) {
246
255
  t20 = (value) => switchTo(value === LIVE ? null : String(value));
247
- $[33] = switchTo;
248
- $[34] = t20;
249
- } else t20 = $[34];
256
+ $[35] = switchTo;
257
+ $[36] = t20;
258
+ } else t20 = $[36];
250
259
  let t21;
251
- if ($[35] === Symbol.for("react.memo_cache_sentinel")) {
260
+ if ($[37] === Symbol.for("react.memo_cache_sentinel")) {
252
261
  t21 = /* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Switch to" });
253
- $[35] = t21;
254
- } else t21 = $[35];
262
+ $[37] = t21;
263
+ } else t21 = $[37];
255
264
  let t22;
256
- if ($[36] === Symbol.for("react.memo_cache_sentinel")) {
265
+ if ($[38] === Symbol.for("react.memo_cache_sentinel")) {
257
266
  t22 = /* @__PURE__ */ jsx("span", { children: "Live" });
258
- $[36] = t22;
259
- } else t22 = $[36];
267
+ $[38] = t22;
268
+ } else t22 = $[38];
260
269
  let t23;
261
- if ($[37] !== list) {
270
+ if ($[39] !== list) {
262
271
  t23 = list && /* @__PURE__ */ jsx("span", {
263
272
  className: "text-muted-foreground text-xs",
264
273
  children: liveLine(list.live)
265
274
  });
266
- $[37] = list;
267
- $[38] = t23;
268
- } else t23 = $[38];
275
+ $[39] = list;
276
+ $[40] = t23;
277
+ } else t23 = $[40];
269
278
  let t24;
270
- if ($[39] !== t23) {
279
+ if ($[41] !== t23) {
271
280
  t24 = /* @__PURE__ */ jsx(DropdownMenuRadioItem, {
272
281
  value: LIVE,
273
282
  closeOnClick: true,
@@ -276,58 +285,58 @@ function DraftPicker(t0) {
276
285
  children: [t22, t23]
277
286
  })
278
287
  });
279
- $[39] = t23;
280
- $[40] = t24;
281
- } else t24 = $[40];
288
+ $[41] = t23;
289
+ $[42] = t24;
290
+ } else t24 = $[42];
282
291
  let t25;
283
- if ($[41] !== drafts) {
292
+ if ($[43] !== drafts) {
284
293
  t25 = drafts.map(_temp6);
285
- $[41] = drafts;
286
- $[42] = t25;
287
- } else t25 = $[42];
294
+ $[43] = drafts;
295
+ $[44] = t25;
296
+ } else t25 = $[44];
288
297
  let t26;
289
- if ($[43] !== t24 || $[44] !== t25) {
298
+ if ($[45] !== t24 || $[46] !== t25) {
290
299
  t26 = /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
291
300
  t21,
292
301
  t24,
293
302
  t25
294
303
  ] });
295
- $[43] = t24;
296
- $[44] = t25;
297
- $[45] = t26;
298
- } else t26 = $[45];
304
+ $[45] = t24;
305
+ $[46] = t25;
306
+ $[47] = t26;
307
+ } else t26 = $[47];
299
308
  let t27;
300
- if ($[46] !== t19 || $[47] !== t20 || $[48] !== t26) {
309
+ if ($[48] !== t19 || $[49] !== t20 || $[50] !== t26) {
301
310
  t27 = /* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
302
311
  value: t19,
303
312
  onValueChange: t20,
304
313
  children: t26
305
314
  });
306
- $[46] = t19;
307
- $[47] = t20;
308
- $[48] = t26;
309
- $[49] = t27;
310
- } else t27 = $[49];
315
+ $[48] = t19;
316
+ $[49] = t20;
317
+ $[50] = t26;
318
+ $[51] = t27;
319
+ } else t27 = $[51];
311
320
  let t28;
312
- if ($[50] !== t18 || $[51] !== t27) {
321
+ if ($[52] !== t18 || $[53] !== t27) {
313
322
  t28 = /* @__PURE__ */ jsx(DropdownMenuContent, {
314
323
  className: "w-80",
315
324
  align: "start",
316
325
  children: /* @__PURE__ */ jsxs(Fragment, { children: [t18, t27] })
317
326
  });
318
- $[50] = t18;
319
- $[51] = t27;
320
- $[52] = t28;
321
- } else t28 = $[52];
327
+ $[52] = t18;
328
+ $[53] = t27;
329
+ $[54] = t28;
330
+ } else t28 = $[54];
322
331
  let t29;
323
- if ($[53] !== t17 || $[54] !== t28) {
332
+ if ($[55] !== t17 || $[56] !== t28) {
324
333
  t29 = /* @__PURE__ */ jsxs(DropdownMenu, { children: [t17, t28] });
325
- $[53] = t17;
326
- $[54] = t28;
327
- $[55] = t29;
328
- } else t29 = $[55];
334
+ $[55] = t17;
335
+ $[56] = t28;
336
+ $[57] = t29;
337
+ } else t29 = $[57];
329
338
  let t30;
330
- if ($[56] !== current?.name || $[57] !== deleting || $[58] !== draftId || $[59] !== leaveDraft || $[60] !== projectId || $[61] !== review) {
339
+ if ($[58] !== current?.name || $[59] !== deleting || $[60] !== draftId || $[61] !== leaveDraft || $[62] !== projectId || $[63] !== review) {
331
340
  t30 = draftId && projectId && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ReviewDraftSheet, {
332
341
  projectId,
333
342
  draftId,
@@ -341,21 +350,21 @@ function DraftPicker(t0) {
341
350
  onOpenChange: _temp8,
342
351
  onDeleted: (ended) => leaveDraft(ended, { discarded: current?.name === null })
343
352
  })] });
344
- $[56] = current?.name;
345
- $[57] = deleting;
346
- $[58] = draftId;
347
- $[59] = leaveDraft;
348
- $[60] = projectId;
349
- $[61] = review;
350
- $[62] = t30;
351
- } else t30 = $[62];
353
+ $[58] = current?.name;
354
+ $[59] = deleting;
355
+ $[60] = draftId;
356
+ $[61] = leaveDraft;
357
+ $[62] = projectId;
358
+ $[63] = review;
359
+ $[64] = t30;
360
+ } else t30 = $[64];
352
361
  let t31;
353
- if ($[63] !== t29 || $[64] !== t30) {
362
+ if ($[65] !== t29 || $[66] !== t30) {
354
363
  t31 = /* @__PURE__ */ jsxs(Fragment, { children: [t29, t30] });
355
- $[63] = t29;
356
- $[64] = t30;
357
- $[65] = t31;
358
- } else t31 = $[65];
364
+ $[65] = t29;
365
+ $[66] = t30;
366
+ $[67] = t31;
367
+ } else t31 = $[67];
359
368
  return t31;
360
369
  }
361
370
  function _temp8(open_0) {
@@ -364,8 +373,8 @@ function _temp8(open_0) {
364
373
  function _temp7(open) {
365
374
  if (!open) studioStore.send({ type: "closeReviewDraftSheet" });
366
375
  }
367
- function _temp6(draft) {
368
- return /* @__PURE__ */ jsx(DraftItem, { draft }, draft.id);
376
+ function _temp6(draft_0) {
377
+ return /* @__PURE__ */ jsx(DraftItem, { draft: draft_0 }, draft_0.id);
369
378
  }
370
379
  function _temp5() {
371
380
  return _temp4;