camox 0.67.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.
- package/dist/core/editing/createEditableBlock.js +2 -1
- package/dist/features/canvas/canvasFrameDocument.js +25 -2
- package/dist/features/canvas/useCanvasFrame.js +6 -2
- package/dist/features/preview/components/PreviewToolbar.js +77 -68
- package/dist/features/preview/components/previewStyles.js +11 -2
- package/dist/features/preview/repeatableItemTargets.js +13 -7
- package/dist/features/provider/AuthenticatedCamoxProvider.js +33 -28
- package/dist/features/renderer/RendererApp.js +202 -154
- package/dist/features/renderer/RendererFrames.js +87 -55
- package/dist/features/renderer/definitionAnswers.js +1 -0
- package/dist/features/renderer/rendererHost.js +4 -0
- package/dist/features/renderer/studioConnection.js +9 -1
- package/dist/features/runtime/RuntimeChrome.js +47 -61
- package/dist/features/runtime/pageNavigation.js +93 -17
- package/dist/features/runtime/rendererClient.js +13 -6
- package/dist/features/studio/components/ChatWidget.js +3 -4
- package/dist/features/studio/components/ConnectAgent.js +33 -59
- package/dist/features/studio/components/DraftBar.js +139 -0
- package/dist/features/studio/components/DraftsControl.js +129 -164
- package/dist/features/studio/components/LocalePicker.js +22 -4
- package/dist/features/studio/components/Navbar.js +3 -2
- package/dist/features/studio/components/ReviewDraftSheet.js +2 -21
- package/dist/features/studio/components/UserButton.js +7 -11
- package/dist/features/studio/studioStore.js +0 -13
- package/dist/features/studio/viewSwitch.js +64 -0
- package/dist/lib/auth.js +5 -1
- package/dist/lib/draft-scope.js +28 -15
- package/dist/lib/studio-reads.js +46 -13
- package/dist/lib/view-switch.js +64 -0
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +4 -4
- package/dist/features/studio/components/UnnamedDraftBar.js +0 -349
|
@@ -7,7 +7,8 @@ import { useLocalePath, useLocalizedPath } from "../../../lib/view-locale.js";
|
|
|
7
7
|
import { STUDIO_BASE_PATH, STUDIO_CONTENT_PATH, STUDIO_SETTINGS_PATH } from "../routes.js";
|
|
8
8
|
import { studioStore } from "../studioStore.js";
|
|
9
9
|
import { UserButton } from "./UserButton.js";
|
|
10
|
-
import {
|
|
10
|
+
import { ConnectAgent } from "./ConnectAgent.js";
|
|
11
|
+
import { DraftPicker } from "./DraftsControl.js";
|
|
11
12
|
import { LocalePicker } from "./LocalePicker.js";
|
|
12
13
|
import { ProjectMenu } from "./ProjectMenu.js";
|
|
13
14
|
import { c } from "react/compiler-runtime";
|
|
@@ -144,7 +145,7 @@ const Navbar = (t0) => {
|
|
|
144
145
|
if ($[23] === Symbol.for("react.memo_cache_sentinel")) {
|
|
145
146
|
t10 = /* @__PURE__ */ jsxs("div", {
|
|
146
147
|
className: "flex items-center gap-2",
|
|
147
|
-
children: [/* @__PURE__ */ jsx(
|
|
148
|
+
children: [/* @__PURE__ */ jsx(ConnectAgent, {}), /* @__PURE__ */ jsx(UserButton, {})]
|
|
148
149
|
});
|
|
149
150
|
$[23] = t10;
|
|
150
151
|
} else t10 = $[23];
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useDraftScope } from "../../../lib/draft-scope.js";
|
|
2
1
|
import { reads, useReadQuery, useStudioCache } from "../../../lib/studio-reads.js";
|
|
3
2
|
import { cn } from "../../../lib/utils.js";
|
|
4
3
|
import { getDraftReadClient } from "../../../lib/api-client.js";
|
|
@@ -9,6 +8,7 @@ import { localeLabel } from "../localeOptions.js";
|
|
|
9
8
|
import { askAgentMessage, findingSentence, fixLabel } from "../findingSentence.js";
|
|
10
9
|
import { useShowInCanvas } from "../showInCanvas.js";
|
|
11
10
|
import { draftLabel, plural, timeAgo } from "../draftLabel.js";
|
|
11
|
+
import { useLeaveDraft } from "../viewSwitch.js";
|
|
12
12
|
import { c } from "react/compiler-runtime";
|
|
13
13
|
import * as React from "react";
|
|
14
14
|
import { CHECKS_RUNNING_ERROR, CONFLICTS_CHANGED_ERROR, FINDINGS_OPEN_ERROR, REVISION_CHANGED_ERROR, TRANSLATIONS_PENDING_ERROR } from "@camox/api-contract/drafts";
|
|
@@ -1133,25 +1133,6 @@ function _temp11(bullet, index) {
|
|
|
1133
1133
|
function _temp10(error) {
|
|
1134
1134
|
return toast.error(error.message || "Could not summarize the draft");
|
|
1135
1135
|
}
|
|
1136
|
-
/** Switches the studio to Live once its draft ended here, replacing the draft's URL entry. */
|
|
1137
|
-
function useLeaveDraft() {
|
|
1138
|
-
const $ = c(2);
|
|
1139
|
-
const draftScope = useDraftScope();
|
|
1140
|
-
let t0;
|
|
1141
|
-
if ($[0] !== draftScope) {
|
|
1142
|
-
t0 = (ended, t1) => {
|
|
1143
|
-
const { discarded: t2 } = t1 === void 0 ? {} : t1;
|
|
1144
|
-
const discarded = t2 === void 0 ? false : t2;
|
|
1145
|
-
draftScope.leave(ended);
|
|
1146
|
-
if (!ended) return;
|
|
1147
|
-
const what = discarded ? "Changes discarded" : `Draft ${ended.outcome}`;
|
|
1148
|
-
toast.success(`${what}. You're now viewing Live.`);
|
|
1149
|
-
};
|
|
1150
|
-
$[0] = draftScope;
|
|
1151
|
-
$[1] = t0;
|
|
1152
|
-
} else t0 = $[1];
|
|
1153
|
-
return t0;
|
|
1154
|
-
}
|
|
1155
1136
|
/**
|
|
1156
1137
|
* Renames a regular draft, whichever draft the studio views: the request names the draft it
|
|
1157
1138
|
* renames. A blank name clears it, so the draft shows its computed label again.
|
|
@@ -1807,4 +1788,4 @@ function _temp14(error) {
|
|
|
1807
1788
|
}
|
|
1808
1789
|
|
|
1809
1790
|
//#endregion
|
|
1810
|
-
export { DeleteDraftDialog, ReviewDraftSheet,
|
|
1791
|
+
export { DeleteDraftDialog, ReviewDraftSheet, useRenameDraft };
|
|
@@ -9,7 +9,6 @@ import { useApplyTheme } from "../useTheme.js";
|
|
|
9
9
|
import { c } from "react/compiler-runtime";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
import { useSelector } from "@xstate/store-react";
|
|
12
|
-
import { Button } from "@camox/ui/button";
|
|
13
12
|
import { Check, Command, EyeOff, LogOut, Monitor, Moon, Settings, Sun, User } from "lucide-react";
|
|
14
13
|
import { Avatar, AvatarFallback, AvatarImage } from "@camox/ui/avatar";
|
|
15
14
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "@camox/ui/dropdown-menu";
|
|
@@ -22,11 +21,7 @@ const UserButton = () => {
|
|
|
22
21
|
if (!isAuthenticated || isLoading) {
|
|
23
22
|
let t0;
|
|
24
23
|
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
25
|
-
t0 = /* @__PURE__ */ jsx(
|
|
26
|
-
variant: "outline",
|
|
27
|
-
size: "icon",
|
|
28
|
-
children: /* @__PURE__ */ jsx(User, { className: "h-4 w-4" })
|
|
29
|
-
});
|
|
24
|
+
t0 = /* @__PURE__ */ jsx(Avatar, { children: /* @__PURE__ */ jsx(AvatarFallback, { children: /* @__PURE__ */ jsx(User, { className: "size-4" }) }) });
|
|
30
25
|
$[0] = t0;
|
|
31
26
|
} else t0 = $[0];
|
|
32
27
|
return t0;
|
|
@@ -62,11 +57,12 @@ function AuthenticatedUserButton({ theme, setTheme }) {
|
|
|
62
57
|
const userImage = session?.user?.image;
|
|
63
58
|
const userInitials = userName.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
|
|
64
59
|
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
60
|
+
"aria-label": "Account",
|
|
61
|
+
className: "focus-visible:ring-ring/50 rounded-full outline-none focus-visible:ring-3",
|
|
62
|
+
children: /* @__PURE__ */ jsxs(Avatar, { children: [userImage && /* @__PURE__ */ jsx(AvatarImage, {
|
|
63
|
+
src: userImage,
|
|
64
|
+
alt: userName
|
|
65
|
+
}), /* @__PURE__ */ jsx(AvatarFallback, { children: userInitials })] })
|
|
70
66
|
}), /* @__PURE__ */ jsxs(DropdownMenuContent, {
|
|
71
67
|
className: "w-72",
|
|
72
68
|
align: "end",
|
|
@@ -10,7 +10,6 @@ const studioStore = createStore({
|
|
|
10
10
|
startRenaming: false
|
|
11
11
|
},
|
|
12
12
|
isDeleteDraftDialogOpen: false,
|
|
13
|
-
isKeepDraftOpen: false,
|
|
14
13
|
localeDialog: null,
|
|
15
14
|
websiteLocation: null,
|
|
16
15
|
agentAsk: null,
|
|
@@ -79,18 +78,6 @@ const studioStore = createStore({
|
|
|
79
78
|
isDeleteDraftDialogOpen: false
|
|
80
79
|
};
|
|
81
80
|
},
|
|
82
|
-
openKeepDraft: (context) => {
|
|
83
|
-
return {
|
|
84
|
-
...context,
|
|
85
|
-
isKeepDraftOpen: true
|
|
86
|
-
};
|
|
87
|
-
},
|
|
88
|
-
closeKeepDraft: (context) => {
|
|
89
|
-
return {
|
|
90
|
-
...context,
|
|
91
|
-
isKeepDraftOpen: false
|
|
92
|
-
};
|
|
93
|
-
},
|
|
94
81
|
openLocaleDialog: (context, event) => {
|
|
95
82
|
return {
|
|
96
83
|
...context,
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { useDraftScope } from "../../lib/draft-scope.js";
|
|
2
|
+
import { useViewShown } from "../../lib/view-switch.js";
|
|
3
|
+
import { c } from "react/compiler-runtime";
|
|
4
|
+
import { toast } from "@camox/ui/toaster";
|
|
5
|
+
|
|
6
|
+
//#region src/features/studio/viewSwitch.ts
|
|
7
|
+
/**
|
|
8
|
+
* Tells the editor the studio heard them while it switches to another draft or locale: the
|
|
9
|
+
* studio keeps showing what it showed until the next view is ready, then shows it at once.
|
|
10
|
+
* `switching` settles once it shows.
|
|
11
|
+
*/
|
|
12
|
+
function toastSwitch(switching, messages) {
|
|
13
|
+
toast.promise(switching, {
|
|
14
|
+
...messages,
|
|
15
|
+
error: "Something went wrong while switching. Reload the page to try again."
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Switches to another draft or locale with `navigate`, which starts the navigation that does,
|
|
20
|
+
* saying so in a toast until the next view shows.
|
|
21
|
+
*/
|
|
22
|
+
function useSwitchView() {
|
|
23
|
+
const $ = c(2);
|
|
24
|
+
const shown = useViewShown();
|
|
25
|
+
let t0;
|
|
26
|
+
if ($[0] !== shown) {
|
|
27
|
+
t0 = (navigate, messages) => toastSwitch(Promise.resolve(navigate()).then(() => shown()), messages);
|
|
28
|
+
$[0] = shown;
|
|
29
|
+
$[1] = t0;
|
|
30
|
+
} else t0 = $[1];
|
|
31
|
+
return t0;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Switches the studio to Live once the draft it views ended, by this member, here or in another
|
|
35
|
+
* tab, replacing the draft's URL entry. Called once the studio already left the draft, it does
|
|
36
|
+
* nothing.
|
|
37
|
+
*/
|
|
38
|
+
function useLeaveDraft() {
|
|
39
|
+
const $ = c(3);
|
|
40
|
+
const draftScope = useDraftScope();
|
|
41
|
+
const shown = useViewShown();
|
|
42
|
+
let t0;
|
|
43
|
+
if ($[0] !== draftScope || $[1] !== shown) {
|
|
44
|
+
t0 = (ended, t1) => {
|
|
45
|
+
const { discarded: t2 } = t1 === void 0 ? {} : t1;
|
|
46
|
+
const discarded = t2 === void 0 ? false : t2;
|
|
47
|
+
if (ended && draftScope.current() !== ended.draftId) return;
|
|
48
|
+
draftScope.leave(ended);
|
|
49
|
+
if (!ended) return;
|
|
50
|
+
const what = discarded ? "Changes discarded" : `Draft ${ended.outcome}`;
|
|
51
|
+
toastSwitch(shown(), {
|
|
52
|
+
loading: `${what}. Switching to Live…`,
|
|
53
|
+
success: `${what}. You're now viewing Live.`
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
$[0] = draftScope;
|
|
57
|
+
$[1] = shown;
|
|
58
|
+
$[2] = t0;
|
|
59
|
+
} else t0 = $[2];
|
|
60
|
+
return t0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
export { useLeaveDraft, useSwitchView };
|
package/dist/lib/auth.js
CHANGED
|
@@ -250,6 +250,10 @@ function useSessionState(authClient, track) {
|
|
|
250
250
|
const subscribe = t1;
|
|
251
251
|
return React.useSyncExternalStore(track ? subscribe : noSubscription, getSnapshot, getSnapshot);
|
|
252
252
|
}
|
|
253
|
+
/** The id of the member signed in, as the session the client holds says: null without one. */
|
|
254
|
+
function signedInUserId(authClient) {
|
|
255
|
+
return authClient.$store.atoms.session.value.data?.user?.id ?? null;
|
|
256
|
+
}
|
|
253
257
|
function useAuthState() {
|
|
254
258
|
const $ = c(10);
|
|
255
259
|
const { authClient, initialAuthenticated: t0, exchangingToken: t1, sessionless: t2 } = useAuthContext();
|
|
@@ -394,4 +398,4 @@ function _temp4() {
|
|
|
394
398
|
}
|
|
395
399
|
|
|
396
400
|
//#endregion
|
|
397
|
-
export { AuthContext, createCamoxAuthClient, getAuthCookieHeader, getAuthRequestCredentials, useAuthActions, useAuthContext, useAuthState, useIsAuthenticated, useProcessOtt, useProjectUuid, useSignInRedirect };
|
|
401
|
+
export { AuthContext, createCamoxAuthClient, getAuthCookieHeader, getAuthRequestCredentials, signedInUserId, useAuthActions, useAuthContext, useAuthState, useIsAuthenticated, useProcessOtt, useProjectUuid, useSignInRedirect };
|
package/dist/lib/draft-scope.js
CHANGED
|
@@ -158,37 +158,50 @@ const DraftScopeContext = React.createContext(null);
|
|
|
158
158
|
/**
|
|
159
159
|
* The draft scope the studio is in, for handlers and effects. Render code reads the draft it
|
|
160
160
|
* views from `useCurrentDraftId`: the scope object never changes, so a memoized render reading
|
|
161
|
-
* `current()` from it would keep showing the draft of its first render
|
|
161
|
+
* `current()` from it would keep showing the draft of its first render, and while a switch to
|
|
162
|
+
* another draft loads, `current()` already names the next one.
|
|
162
163
|
*/
|
|
163
164
|
function useDraftScope() {
|
|
164
165
|
const scope = React.useContext(DraftScopeContext);
|
|
165
166
|
if (!scope) throw new Error("useDraftScope must be used inside a DraftScopeContext provider");
|
|
166
167
|
return scope;
|
|
167
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* The draft the page runtime's committed render shows, or null for Live: undefined outside it.
|
|
171
|
+
* A switch to another draft renders in a transition, so until it commits the studio keeps
|
|
172
|
+
* showing the draft it was in, while the scope already reads and writes the next one.
|
|
173
|
+
*/
|
|
174
|
+
const ShownDraftContext = React.createContext(void 0);
|
|
168
175
|
const noScope = () => null;
|
|
169
176
|
const noSubscription = () => () => {};
|
|
177
|
+
/** The draft the render shows: the committed one in the page runtime, the scope's elsewhere. */
|
|
178
|
+
function useShownDraft(scope) {
|
|
179
|
+
const shown = React.use(ShownDraftContext);
|
|
180
|
+
const current = scope?.current ?? noScope;
|
|
181
|
+
const followed = shown === void 0 && scope ? scope.subscribe : noSubscription;
|
|
182
|
+
const draftId = React.useSyncExternalStore(followed, current, current);
|
|
183
|
+
return shown === void 0 ? draftId : shown;
|
|
184
|
+
}
|
|
170
185
|
/** The draft the studio is in, or null for Live. The caller re-renders after every move. */
|
|
171
186
|
function useCurrentDraftId() {
|
|
172
|
-
|
|
173
|
-
return React.useSyncExternalStore(scope.subscribe, scope.current, scope.current);
|
|
187
|
+
return useShownDraft(useDraftScope());
|
|
174
188
|
}
|
|
175
189
|
/** The draft scope and the draft it views, outside the studio too, where there is none. */
|
|
176
190
|
function useOptionalDraftScope() {
|
|
177
191
|
const $ = c(3);
|
|
178
192
|
const scope = React.useContext(DraftScopeContext);
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
t0 = {
|
|
193
|
+
const t0 = useShownDraft(scope);
|
|
194
|
+
let t1;
|
|
195
|
+
if ($[0] !== scope || $[1] !== t0) {
|
|
196
|
+
t1 = {
|
|
184
197
|
scope,
|
|
185
|
-
draftId
|
|
198
|
+
draftId: t0
|
|
186
199
|
};
|
|
187
|
-
$[0] =
|
|
188
|
-
$[1] =
|
|
189
|
-
$[2] =
|
|
190
|
-
} else
|
|
191
|
-
return
|
|
200
|
+
$[0] = scope;
|
|
201
|
+
$[1] = t0;
|
|
202
|
+
$[2] = t1;
|
|
203
|
+
} else t1 = $[2];
|
|
204
|
+
return t1;
|
|
192
205
|
}
|
|
193
206
|
/**
|
|
194
207
|
* Follows the draft a browser URL names, for a studio mounted in a host application, whose
|
|
@@ -199,4 +212,4 @@ function followUrl(scope, href) {
|
|
|
199
212
|
}
|
|
200
213
|
|
|
201
214
|
//#endregion
|
|
202
|
-
export { DraftScopeContext, createDraftScope, draftNamedBy, followUrl, useCurrentDraftId, useDraftScope, useOptionalDraftScope, withoutDraft };
|
|
215
|
+
export { DraftScopeContext, ShownDraftContext, createDraftScope, draftNamedBy, followUrl, useCurrentDraftId, useDraftScope, useOptionalDraftScope, withoutDraft };
|
package/dist/lib/studio-reads.js
CHANGED
|
@@ -2,11 +2,12 @@ import { useCurrentDraftId } from "./draft-scope.js";
|
|
|
2
2
|
import { ViewLocaleContext } from "./view-locale-context.js";
|
|
3
3
|
import { fetchRuntimeJson } from "../features/runtime/navigationTarget.js";
|
|
4
4
|
import { collectFileIds } from "./normalized-data.js";
|
|
5
|
+
import { useSwitchHold } from "./view-switch.js";
|
|
5
6
|
import { c } from "react/compiler-runtime";
|
|
6
7
|
import * as React from "react";
|
|
7
8
|
import { inScope, queryKeys, scopeOfKey } from "@camox/api-contract/query-keys";
|
|
8
9
|
import { PATROLLER_IDS } from "@camox/api-contract/patrol";
|
|
9
|
-
import { useQueries, useQuery, useSuspenseQuery } from "@tanstack/react-query";
|
|
10
|
+
import { useQueries, useQuery, useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
|
|
10
11
|
|
|
11
12
|
//#region src/lib/studio-reads.ts
|
|
12
13
|
function entry(definition) {
|
|
@@ -505,7 +506,7 @@ function useStudioCache() {
|
|
|
505
506
|
}
|
|
506
507
|
/**
|
|
507
508
|
* The draft and locale the caller's render shows, which its reads name: the read hooks re-render
|
|
508
|
-
* after a move to another draft
|
|
509
|
+
* after a move to another draft or locale, reading its keys.
|
|
509
510
|
*/
|
|
510
511
|
function useShownTarget() {
|
|
511
512
|
const $ = c(3);
|
|
@@ -548,7 +549,7 @@ function useRead(read) {
|
|
|
548
549
|
* the locale the caller's render shows, unless `locale` names another.
|
|
549
550
|
*/
|
|
550
551
|
function useReadQuery(read, t0) {
|
|
551
|
-
const $ = c(
|
|
552
|
+
const $ = c(18);
|
|
552
553
|
let t1;
|
|
553
554
|
if ($[0] !== t0) {
|
|
554
555
|
t1 = t0 === void 0 ? {} : t0;
|
|
@@ -558,6 +559,7 @@ function useReadQuery(read, t0) {
|
|
|
558
559
|
const { enabled, select, locale } = t1;
|
|
559
560
|
const shown = useShownTarget();
|
|
560
561
|
const cache = useStudioCache();
|
|
562
|
+
const queryClient = useQueryClient();
|
|
561
563
|
let t2;
|
|
562
564
|
if ($[2] !== locale || $[3] !== shown) {
|
|
563
565
|
t2 = locale ? {
|
|
@@ -577,24 +579,38 @@ function useReadQuery(read, t0) {
|
|
|
577
579
|
$[7] = read;
|
|
578
580
|
$[8] = t3;
|
|
579
581
|
} else t3 = $[8];
|
|
582
|
+
const options = t3;
|
|
580
583
|
let t4;
|
|
581
|
-
if ($[9] !== enabled || $[10] !==
|
|
584
|
+
if ($[9] !== enabled || $[10] !== options || $[11] !== select) {
|
|
582
585
|
t4 = {
|
|
583
|
-
...
|
|
586
|
+
...options,
|
|
584
587
|
enabled,
|
|
585
588
|
select
|
|
586
589
|
};
|
|
587
590
|
$[9] = enabled;
|
|
588
|
-
$[10] =
|
|
589
|
-
$[11] =
|
|
591
|
+
$[10] = options;
|
|
592
|
+
$[11] = select;
|
|
590
593
|
$[12] = t4;
|
|
591
594
|
} else t4 = $[12];
|
|
592
|
-
|
|
595
|
+
const result = useQuery(t4);
|
|
596
|
+
let t5;
|
|
597
|
+
if ($[13] !== enabled || $[14] !== options || $[15] !== queryClient || $[16] !== result) {
|
|
598
|
+
t5 = () => enabled !== false && result.isPending ? queryClient.fetchQuery(options) : null;
|
|
599
|
+
$[13] = enabled;
|
|
600
|
+
$[14] = options;
|
|
601
|
+
$[15] = queryClient;
|
|
602
|
+
$[16] = result;
|
|
603
|
+
$[17] = t5;
|
|
604
|
+
} else t5 = $[17];
|
|
605
|
+
const hold = useSwitchHold(t5);
|
|
606
|
+
if (hold) throw hold;
|
|
607
|
+
return result;
|
|
593
608
|
}
|
|
594
609
|
function useReadQueries(list, combine) {
|
|
595
|
-
const $ = c(
|
|
610
|
+
const $ = c(13);
|
|
596
611
|
const inDraft = useShownTarget();
|
|
597
612
|
const cache = useStudioCache();
|
|
613
|
+
const queryClient = useQueryClient();
|
|
598
614
|
let t0;
|
|
599
615
|
if ($[0] !== cache || $[1] !== inDraft || $[2] !== list) {
|
|
600
616
|
let t1;
|
|
@@ -610,17 +626,34 @@ function useReadQueries(list, combine) {
|
|
|
610
626
|
$[2] = list;
|
|
611
627
|
$[3] = t0;
|
|
612
628
|
} else t0 = $[3];
|
|
629
|
+
const queries = t0;
|
|
613
630
|
let t1;
|
|
614
|
-
if ($[7] !== combine || $[8] !==
|
|
631
|
+
if ($[7] !== combine || $[8] !== queries) {
|
|
615
632
|
t1 = {
|
|
616
|
-
queries
|
|
633
|
+
queries,
|
|
617
634
|
combine
|
|
618
635
|
};
|
|
619
636
|
$[7] = combine;
|
|
620
|
-
$[8] =
|
|
637
|
+
$[8] = queries;
|
|
621
638
|
$[9] = t1;
|
|
622
639
|
} else t1 = $[9];
|
|
623
|
-
|
|
640
|
+
const combined = useQueries(t1);
|
|
641
|
+
let t2;
|
|
642
|
+
if ($[10] !== queries || $[11] !== queryClient) {
|
|
643
|
+
t2 = () => {
|
|
644
|
+
const loading = queries.filter((t3) => {
|
|
645
|
+
const { queryKey } = t3;
|
|
646
|
+
return (queryClient.getQueryState(queryKey)?.status ?? "pending") === "pending";
|
|
647
|
+
});
|
|
648
|
+
return loading.length ? Promise.all(loading.map((options) => queryClient.fetchQuery(options))) : null;
|
|
649
|
+
};
|
|
650
|
+
$[10] = queries;
|
|
651
|
+
$[11] = queryClient;
|
|
652
|
+
$[12] = t2;
|
|
653
|
+
} else t2 = $[12];
|
|
654
|
+
const hold = useSwitchHold(t2);
|
|
655
|
+
if (hold) throw hold;
|
|
656
|
+
return combined;
|
|
624
657
|
}
|
|
625
658
|
|
|
626
659
|
//#endregion
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { c } from "react/compiler-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/view-switch.ts
|
|
5
|
+
const ViewSwitchesContext = React.createContext(null);
|
|
6
|
+
/**
|
|
7
|
+
* Set while a render switches to another view: the time after which it stops waiting for reads
|
|
8
|
+
* and commits with what it has. Null otherwise.
|
|
9
|
+
*/
|
|
10
|
+
const ViewSwitchDeadlineContext = React.createContext(null);
|
|
11
|
+
/** How long a switch waits for the next view before showing it however far it got. */
|
|
12
|
+
const SWITCH_WAIT_MS = 1e4;
|
|
13
|
+
/** Prepares the studio's part of every switch with `preparer`, while mounted. */
|
|
14
|
+
function useViewPreparer(preparer) {
|
|
15
|
+
const $ = c(5);
|
|
16
|
+
const switches = React.use(ViewSwitchesContext);
|
|
17
|
+
const prepare = React.useEffectEvent(preparer);
|
|
18
|
+
let t0;
|
|
19
|
+
if ($[0] !== prepare || $[1] !== switches) {
|
|
20
|
+
t0 = () => switches?.prepare((next) => prepare(next));
|
|
21
|
+
$[0] = prepare;
|
|
22
|
+
$[1] = switches;
|
|
23
|
+
$[2] = t0;
|
|
24
|
+
} else t0 = $[2];
|
|
25
|
+
let t1;
|
|
26
|
+
if ($[3] !== switches) {
|
|
27
|
+
t1 = [switches];
|
|
28
|
+
$[3] = switches;
|
|
29
|
+
$[4] = t1;
|
|
30
|
+
} else t1 = $[4];
|
|
31
|
+
React.useEffect(t0, t1);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The last navigation started, settling once it shows: for the studio to say a switch it started,
|
|
35
|
+
* or one that followed what it did, is under way. Outside the page runtime, it settles at once.
|
|
36
|
+
*/
|
|
37
|
+
function useViewShown() {
|
|
38
|
+
const $ = c(2);
|
|
39
|
+
const switches = React.use(ViewSwitchesContext);
|
|
40
|
+
let t0;
|
|
41
|
+
if ($[0] !== switches) {
|
|
42
|
+
t0 = () => switches?.shown() ?? Promise.resolve();
|
|
43
|
+
$[0] = switches;
|
|
44
|
+
$[1] = t0;
|
|
45
|
+
} else t0 = $[1];
|
|
46
|
+
return t0;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* While a render switches views, a read still loading holds the switch back rather than show
|
|
50
|
+
* its loading state: the promise to suspend on until it loads or the switch stops waiting.
|
|
51
|
+
* Undefined when the render should show the read as it is.
|
|
52
|
+
*/
|
|
53
|
+
function useSwitchHold(loading) {
|
|
54
|
+
const deadline = React.use(ViewSwitchDeadlineContext);
|
|
55
|
+
if (deadline === null) return void 0;
|
|
56
|
+
const left = deadline - Date.now();
|
|
57
|
+
if (left <= 0) return void 0;
|
|
58
|
+
const pending = loading();
|
|
59
|
+
if (!pending) return void 0;
|
|
60
|
+
return Promise.race([pending.catch(() => {}), new Promise((resolve) => setTimeout(resolve, left))]);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
export { SWITCH_WAIT_MS, ViewSwitchDeadlineContext, ViewSwitchesContext, useSwitchHold, useViewPreparer, useViewShown };
|
package/dist/package.js
CHANGED