camox 0.40.0 → 0.41.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/PlatformLabel.js +62 -0
- package/dist/core/components/lexical/GradientNode.js +126 -0
- package/dist/core/components/lexical/InlineLexicalEditor.js +37 -56
- package/dist/core/components/lexical/InlineStylesPlugin.js +183 -0
- package/dist/core/components/lexical/SelectionBroadcaster.js +49 -46
- package/dist/core/components/lexical/SidebarLexicalEditor.js +197 -151
- package/dist/core/components/lexical/editorConfig.js +25 -7
- package/dist/core/components/lexical/selectTextLink.js +21 -0
- package/dist/core/createApp.d.ts +30 -17
- package/dist/core/createApp.js +14 -3
- package/dist/core/createBlock.d.ts +2 -2
- package/dist/core/createBlock.js +17 -28
- package/dist/core/createLayout.d.ts +48 -4
- package/dist/core/createLayout.js +51 -23
- package/dist/core/derivedRoutes.js +36 -0
- package/dist/core/editing/BlockEditingRuntime.js +4 -4
- package/dist/core/editing/CompleteBlockEditingRuntime.js +5 -5
- package/dist/core/editing/createEditableBlock.d.ts +9 -8
- package/dist/core/editing/createEditableBlock.js +265 -403
- package/dist/core/hooks/useIsEditable.js +4 -7
- package/dist/core/hooks/useRequireDraftSource.js +7 -11
- package/dist/core/lib/lexicalReact.d.ts +1 -26
- package/dist/core/lib/lexicalReact.js +46 -60
- package/dist/core/lib/lexicalState.js +164 -81
- package/dist/core/lib/modifierFormats.js +4 -15
- package/dist/core/lib/textStyles.d.ts +27 -0
- package/dist/core/lib/textStyles.js +47 -0
- package/dist/features/navigation/navigation.d.ts +2 -0
- package/dist/features/navigation/navigation.js +51 -46
- package/dist/features/page/DerivedPageContent.js +61 -0
- package/dist/features/page/PublishedPageContent.js +52 -83
- package/dist/features/page/SharedLayoutContent.js +66 -0
- package/dist/features/preview/CamoxPreview.d.ts +16 -1
- package/dist/features/preview/CamoxPreview.js +246 -290
- package/dist/features/preview/DerivedPreview.js +134 -0
- package/dist/features/preview/EditablePageExperience.js +25 -8
- package/dist/features/preview/components/AddBlockSidebar.js +43 -33
- package/dist/features/preview/components/AssetLightbox.js +1 -1
- package/dist/features/preview/components/BlockActionsPopover.js +8 -8
- package/dist/features/preview/components/BlockThumbnail.js +192 -0
- package/dist/features/preview/components/CreatePageModal.js +123 -115
- package/dist/features/preview/components/DerivedLayoutDialog.js +100 -0
- package/dist/features/preview/components/DerivedLayoutSidebar.d.ts +5 -0
- package/dist/features/preview/components/DerivedLayoutSidebar.js +160 -0
- package/dist/features/preview/components/DerivedPageInfoSidebar.js +57 -0
- package/dist/features/preview/components/FieldToolbar.js +42 -20
- package/dist/features/preview/components/Frame.js +133 -140
- package/dist/features/preview/components/LeftSidebar.js +42 -38
- package/dist/features/preview/components/LinkFieldEditor.js +3 -4
- package/dist/features/preview/components/MobilePreviewDrawer.js +4 -4
- package/dist/features/preview/components/Overlays.js +59 -47
- package/dist/features/preview/components/PageEditorSidebar.js +194 -203
- package/dist/features/preview/components/PageInfoSidebar.js +63 -55
- package/dist/features/preview/components/PageNavigatorSidebar.js +34 -483
- package/dist/features/preview/components/PagePicker.js +205 -153
- package/dist/features/preview/components/PageTree.js +366 -340
- package/dist/features/preview/components/PreviewActivation.js +78 -0
- package/dist/features/preview/components/PreviewPanel.js +98 -68
- package/dist/features/preview/components/PreviewToolbar.js +224 -241
- package/dist/features/preview/components/PreviewToolbarSpacer.js +43 -0
- package/dist/features/preview/components/PublicationRow.js +425 -0
- package/dist/features/preview/components/PublishDialog.js +180 -97
- package/dist/features/preview/components/RightSidebar.js +19 -34
- package/dist/features/preview/components/previewStyles.js +8 -0
- package/dist/features/preview/components/useUpdateBlockPosition.js +7 -13
- package/dist/features/preview/previewConstants.js +8 -0
- package/dist/features/preview/previewStore.js +18 -39
- package/dist/features/preview/publication.js +71 -0
- package/dist/features/provider/AuthenticatedCamoxProvider.js +2 -1
- package/dist/features/provider/CoreCamoxProvider.js +11 -2
- package/dist/features/provider/LocalhostPreviewProvider.js +6 -7
- package/dist/features/provider/useAdminShortcuts.js +5 -4
- package/dist/features/routes/pageRuntime.d.ts +10 -0
- package/dist/features/routes/pageRuntime.js +7 -9
- package/dist/features/runtime/PreviewDocumentContext.js +7 -0
- package/dist/features/runtime/RuntimeChrome.js +149 -0
- package/dist/features/runtime/SharedChromeContext.js +7 -0
- package/dist/features/runtime/navigationRequest.js +21 -0
- package/dist/features/runtime/navigationTarget.js +23 -0
- package/dist/features/runtime/pageApp.js +196 -121
- package/dist/features/runtime/pageNavigation.js +79 -130
- package/dist/features/runtime/runtime.d.ts +11 -0
- package/dist/features/runtime/runtime.js +183 -47
- package/dist/features/runtime/studioApp.d.ts +2 -11
- package/dist/features/runtime/studioApp.js +14 -177
- package/dist/features/studio/CamoxStudio.js +27 -13
- package/dist/features/studio/components/Navbar.js +80 -74
- package/dist/features/studio/components/UserButton.js +4 -4
- package/dist/features/studio/studioTheme.js +25 -0
- package/dist/features/studio/useTheme.js +94 -109
- package/dist/features/vite/appGeneration.js +12 -3
- package/dist/features/vite/definitionsSync.js +4 -2
- package/dist/features/vite/layoutGeneration.js +38 -0
- package/dist/features/vite/runtimeDev.js +3 -1
- package/dist/lib/auth.js +15 -13
- package/dist/lib/normalized-data.js +4 -4
- package/dist/lib/platform.js +13 -0
- package/dist/lib/utils.js +90 -38
- package/dist/studio-overlays.css +5 -40
- package/dist/studio.css +1 -1
- package/package.json +8 -4
- package/skills/camox/SKILL.md +2 -0
- package/skills/camox/references/block-definitions.md +31 -12
- package/skills/camox/references/layout-definitions.md +2 -0
- package/dist/core/lib/modifiers.js +0 -24
- package/dist/features/preview/components/DraftSwitchDialog.js +0 -66
- package/dist/features/preview/previewQueryFns.js +0 -23
- package/dist/features/runtime/studioNavigation.js +0 -120
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import { useAuthState } from "../../lib/auth.js";
|
|
1
|
+
import { useAuthState, useSignInRedirect } from "../../lib/auth.js";
|
|
2
|
+
import { PreviewDocumentContext } from "./PreviewDocumentContext.js";
|
|
3
|
+
import { PreviewActivation } from "../preview/components/PreviewActivation.js";
|
|
4
|
+
import { Frame } from "../preview/components/Frame.js";
|
|
2
5
|
import { CoreCamoxProvider, isLocalhostPreview } from "../provider/CoreCamoxProvider.js";
|
|
6
|
+
import { DerivedPageContent } from "../page/DerivedPageContent.js";
|
|
3
7
|
import { PublishedPageExperience } from "../page/PublishedPageExperience.js";
|
|
4
8
|
import { PageNavigationProvider } from "./pageNavigation.js";
|
|
9
|
+
import { RuntimeChrome } from "./RuntimeChrome.js";
|
|
5
10
|
import { c } from "react/compiler-runtime";
|
|
6
11
|
import { HydrationBoundary, QueryClientProvider } from "@tanstack/react-query";
|
|
7
12
|
import * as React from "react";
|
|
@@ -9,76 +14,75 @@ import { jsx } from "react/jsx-runtime";
|
|
|
9
14
|
|
|
10
15
|
//#region src/features/runtime/pageApp.tsx
|
|
11
16
|
function PageApp(t0) {
|
|
12
|
-
const $ = c(
|
|
13
|
-
if ($[0] !== "
|
|
14
|
-
for (let $i = 0; $i <
|
|
15
|
-
$[0] = "
|
|
17
|
+
const $ = c(19);
|
|
18
|
+
if ($[0] !== "9929b5234f34e8dc8642da9eb491a90e9a57f3ab875ddfc1a186f42f4452f2f5") {
|
|
19
|
+
for (let $i = 0; $i < 19; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
20
|
+
$[0] = "9929b5234f34e8dc8642da9eb491a90e9a57f3ab875ddfc1a186f42f4452f2f5";
|
|
16
21
|
}
|
|
17
22
|
const { camoxApp, input, queryClient } = t0;
|
|
18
23
|
const t1 = input.dehydratedState;
|
|
19
24
|
let t2;
|
|
20
|
-
if ($[1] !== camoxApp || $[2] !== input || $[3] !== queryClient) {
|
|
21
|
-
t2 = /* @__PURE__ */ jsx(
|
|
22
|
-
camoxApp,
|
|
23
|
-
input,
|
|
24
|
-
queryClient
|
|
25
|
-
});
|
|
26
|
-
$[1] = camoxApp;
|
|
27
|
-
$[2] = input;
|
|
28
|
-
$[3] = queryClient;
|
|
29
|
-
$[4] = t2;
|
|
30
|
-
} else t2 = $[4];
|
|
31
|
-
let t3;
|
|
32
|
-
if ($[5] !== camoxApp || $[6] !== input.apiUrl || $[7] !== input.authenticationUrl || $[8] !== input.environmentName || $[9] !== input.projectSlug || $[10] !== t2) {
|
|
33
|
-
t3 = /* @__PURE__ */ jsx(CoreCamoxProvider, {
|
|
25
|
+
if ($[1] !== camoxApp || $[2] !== input.apiUrl || $[3] !== input.authenticationUrl || $[4] !== input.environmentName || $[5] !== input.presentation || $[6] !== input.projectSlug || $[7] !== queryClient) {
|
|
26
|
+
t2 = (currentInput) => /* @__PURE__ */ jsx(CoreCamoxProvider, {
|
|
34
27
|
camoxApp,
|
|
35
28
|
authenticationUrl: input.authenticationUrl,
|
|
36
29
|
apiUrl: input.apiUrl,
|
|
37
30
|
projectSlug: input.projectSlug,
|
|
38
31
|
environmentName: input.environmentName,
|
|
39
|
-
|
|
32
|
+
initialAuthenticated: input.presentation === "studio",
|
|
33
|
+
initialProject: currentInput.project,
|
|
34
|
+
children: /* @__PURE__ */ jsx(PreviewDocumentContext.Provider, {
|
|
35
|
+
value: currentInput.previewDocument,
|
|
36
|
+
children: /* @__PURE__ */ jsx(PageExperience, {
|
|
37
|
+
camoxApp,
|
|
38
|
+
input: currentInput,
|
|
39
|
+
queryClient,
|
|
40
|
+
studioDocument: input.presentation === "studio"
|
|
41
|
+
})
|
|
42
|
+
})
|
|
40
43
|
});
|
|
41
|
-
$[
|
|
42
|
-
$[
|
|
43
|
-
$[
|
|
44
|
-
$[
|
|
45
|
-
$[
|
|
46
|
-
$[
|
|
47
|
-
$[
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
$[1] = camoxApp;
|
|
45
|
+
$[2] = input.apiUrl;
|
|
46
|
+
$[3] = input.authenticationUrl;
|
|
47
|
+
$[4] = input.environmentName;
|
|
48
|
+
$[5] = input.presentation;
|
|
49
|
+
$[6] = input.projectSlug;
|
|
50
|
+
$[7] = queryClient;
|
|
51
|
+
$[8] = t2;
|
|
52
|
+
} else t2 = $[8];
|
|
53
|
+
let t3;
|
|
54
|
+
if ($[9] !== input || $[10] !== queryClient || $[11] !== t2) {
|
|
55
|
+
t3 = /* @__PURE__ */ jsx(PageNavigationProvider, {
|
|
52
56
|
initialInput: input,
|
|
53
57
|
queryClient,
|
|
58
|
+
children: t2
|
|
59
|
+
});
|
|
60
|
+
$[9] = input;
|
|
61
|
+
$[10] = queryClient;
|
|
62
|
+
$[11] = t2;
|
|
63
|
+
$[12] = t3;
|
|
64
|
+
} else t3 = $[12];
|
|
65
|
+
let t4;
|
|
66
|
+
if ($[13] !== t1 || $[14] !== t3) {
|
|
67
|
+
t4 = /* @__PURE__ */ jsx(HydrationBoundary, {
|
|
68
|
+
state: t1,
|
|
54
69
|
children: t3
|
|
55
70
|
});
|
|
56
|
-
$[
|
|
57
|
-
$[13] = queryClient;
|
|
71
|
+
$[13] = t1;
|
|
58
72
|
$[14] = t3;
|
|
59
73
|
$[15] = t4;
|
|
60
74
|
} else t4 = $[15];
|
|
61
75
|
let t5;
|
|
62
|
-
if ($[16] !==
|
|
63
|
-
t5 = /* @__PURE__ */ jsx(
|
|
64
|
-
|
|
76
|
+
if ($[16] !== queryClient || $[17] !== t4) {
|
|
77
|
+
t5 = /* @__PURE__ */ jsx(QueryClientProvider, {
|
|
78
|
+
client: queryClient,
|
|
65
79
|
children: t4
|
|
66
80
|
});
|
|
67
|
-
$[16] =
|
|
81
|
+
$[16] = queryClient;
|
|
68
82
|
$[17] = t4;
|
|
69
83
|
$[18] = t5;
|
|
70
84
|
} else t5 = $[18];
|
|
71
|
-
|
|
72
|
-
if ($[19] !== queryClient || $[20] !== t5) {
|
|
73
|
-
t6 = /* @__PURE__ */ jsx(QueryClientProvider, {
|
|
74
|
-
client: queryClient,
|
|
75
|
-
children: t5
|
|
76
|
-
});
|
|
77
|
-
$[19] = queryClient;
|
|
78
|
-
$[20] = t5;
|
|
79
|
-
$[21] = t6;
|
|
80
|
-
} else t6 = $[21];
|
|
81
|
-
return t6;
|
|
85
|
+
return t5;
|
|
82
86
|
}
|
|
83
87
|
const LazyEditablePageExperience = React.lazy(() => import("../preview/EditablePageExperience.js").then((module) => ({ default: module.EditablePageExperience })));
|
|
84
88
|
const LazyLocalhostPreviewProvider = React.lazy(() => import("../provider/LocalhostPreviewProvider.js").then((module) => ({ default: module.LocalhostPreviewProvider })));
|
|
@@ -88,100 +92,171 @@ var EditingActivationBoundary = class extends React.Component {
|
|
|
88
92
|
return { failed: true };
|
|
89
93
|
}
|
|
90
94
|
componentDidCatch(error) {
|
|
91
|
-
console.error("Camox editing runtime failed to load
|
|
95
|
+
console.error("Camox editing runtime failed to load.", error);
|
|
92
96
|
}
|
|
93
97
|
render() {
|
|
94
|
-
|
|
95
|
-
return this.props.children;
|
|
98
|
+
return this.state.failed ? this.props.fallback : this.props.children;
|
|
96
99
|
}
|
|
97
100
|
};
|
|
101
|
+
const subscribeToHydration = () => () => {};
|
|
98
102
|
function PageExperience(t0) {
|
|
99
|
-
const $ = c(
|
|
100
|
-
if ($[0] !== "
|
|
101
|
-
for (let $i = 0; $i <
|
|
102
|
-
$[0] = "
|
|
103
|
+
const $ = c(39);
|
|
104
|
+
if ($[0] !== "9929b5234f34e8dc8642da9eb491a90e9a57f3ab875ddfc1a186f42f4452f2f5") {
|
|
105
|
+
for (let $i = 0; $i < 39; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
106
|
+
$[0] = "9929b5234f34e8dc8642da9eb491a90e9a57f3ab875ddfc1a186f42f4452f2f5";
|
|
103
107
|
}
|
|
104
|
-
const { camoxApp, input, queryClient } = t0;
|
|
105
|
-
const { isAuthenticated } = useAuthState();
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
const shouldActivateEditing = isAuthenticated || input.source === "draft" || hasOtt;
|
|
108
|
+
const { camoxApp, input, queryClient, studioDocument } = t0;
|
|
109
|
+
const { isAuthenticated, isLoading } = useAuthState();
|
|
110
|
+
const hasHydrated = React.useSyncExternalStore(subscribeToHydration, _temp, _temp2);
|
|
111
|
+
const signIn = useSignInRedirect();
|
|
109
112
|
let t1;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
113
|
+
let t2;
|
|
114
|
+
if ($[1] !== input.routeKind || $[2] !== isAuthenticated || $[3] !== isLoading || $[4] !== signIn) {
|
|
115
|
+
t1 = () => {
|
|
116
|
+
if (input.routeKind && !isAuthenticated && !isLoading) signIn();
|
|
117
|
+
};
|
|
118
|
+
t2 = [
|
|
119
|
+
input.routeKind,
|
|
120
|
+
isAuthenticated,
|
|
121
|
+
isLoading,
|
|
122
|
+
signIn
|
|
123
|
+
];
|
|
124
|
+
$[1] = input.routeKind;
|
|
125
|
+
$[2] = isAuthenticated;
|
|
126
|
+
$[3] = isLoading;
|
|
127
|
+
$[4] = signIn;
|
|
128
|
+
$[5] = t1;
|
|
129
|
+
$[6] = t2;
|
|
130
|
+
} else {
|
|
131
|
+
t1 = $[5];
|
|
132
|
+
t2 = $[6];
|
|
133
|
+
}
|
|
134
|
+
React.useEffect(t1, t2);
|
|
135
|
+
let t3;
|
|
136
|
+
if ($[7] !== camoxApp || $[8] !== input.derived || $[9] !== input.routeKind || $[10] !== input.source) {
|
|
137
|
+
t3 = input.routeKind ? /* @__PURE__ */ jsx("div", {
|
|
138
|
+
className: "text-muted-foreground p-6 text-sm",
|
|
139
|
+
children: "Loading Studio…"
|
|
140
|
+
}) : input.derived ? /* @__PURE__ */ jsx(DerivedPageContent, {
|
|
141
|
+
camoxApp,
|
|
142
|
+
derived: input.derived,
|
|
143
|
+
source: input.source
|
|
144
|
+
}) : /* @__PURE__ */ jsx(PublishedPageExperience, { source: input.source });
|
|
145
|
+
$[7] = camoxApp;
|
|
146
|
+
$[8] = input.derived;
|
|
147
|
+
$[9] = input.routeKind;
|
|
148
|
+
$[10] = input.source;
|
|
149
|
+
$[11] = t3;
|
|
150
|
+
} else t3 = $[11];
|
|
151
|
+
const published = t3;
|
|
152
|
+
let t4;
|
|
153
|
+
if ($[12] !== published) {
|
|
154
|
+
t4 = /* @__PURE__ */ jsx(Frame, { children: published });
|
|
155
|
+
$[12] = published;
|
|
156
|
+
$[13] = t4;
|
|
157
|
+
} else t4 = $[13];
|
|
158
|
+
const isolatedPage = t4;
|
|
159
|
+
const fallback = input.routeKind ? published : isolatedPage;
|
|
160
|
+
if (isAuthenticated) {
|
|
161
|
+
let t5;
|
|
162
|
+
if ($[14] !== camoxApp || $[15] !== hasHydrated || $[16] !== input || $[17] !== queryClient) {
|
|
163
|
+
t5 = hasHydrated ? /* @__PURE__ */ jsx(LazyEditablePageExperience, {
|
|
120
164
|
camoxApp,
|
|
121
165
|
input,
|
|
122
166
|
queryClient
|
|
167
|
+
}) : null;
|
|
168
|
+
$[14] = camoxApp;
|
|
169
|
+
$[15] = hasHydrated;
|
|
170
|
+
$[16] = input;
|
|
171
|
+
$[17] = queryClient;
|
|
172
|
+
$[18] = t5;
|
|
173
|
+
} else t5 = $[18];
|
|
174
|
+
const editor = t5;
|
|
175
|
+
let t6;
|
|
176
|
+
if ($[19] !== editor || $[20] !== fallback || $[21] !== input.previewDocument || $[22] !== input.routeKind || $[23] !== published) {
|
|
177
|
+
t6 = input.routeKind ? /* @__PURE__ */ jsx(React.Suspense, {
|
|
178
|
+
fallback,
|
|
179
|
+
children: editor ?? fallback
|
|
180
|
+
}) : /* @__PURE__ */ jsx(PreviewActivation, {
|
|
181
|
+
fallback: /* @__PURE__ */ jsx(Frame, {
|
|
182
|
+
serverOnly: !!input.previewDocument,
|
|
183
|
+
children: published
|
|
184
|
+
}),
|
|
185
|
+
children: editor
|
|
123
186
|
});
|
|
124
|
-
$[
|
|
125
|
-
$[
|
|
126
|
-
$[
|
|
127
|
-
$[
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
187
|
+
$[19] = editor;
|
|
188
|
+
$[20] = fallback;
|
|
189
|
+
$[21] = input.previewDocument;
|
|
190
|
+
$[22] = input.routeKind;
|
|
191
|
+
$[23] = published;
|
|
192
|
+
$[24] = t6;
|
|
193
|
+
} else t6 = $[24];
|
|
194
|
+
let t7;
|
|
195
|
+
if ($[25] !== fallback || $[26] !== t6) {
|
|
196
|
+
t7 = /* @__PURE__ */ jsx(EditingActivationBoundary, {
|
|
197
|
+
fallback,
|
|
198
|
+
children: t6
|
|
134
199
|
});
|
|
135
|
-
$[
|
|
136
|
-
$[
|
|
137
|
-
$[
|
|
138
|
-
} else
|
|
139
|
-
let
|
|
140
|
-
if ($[
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
children:
|
|
200
|
+
$[25] = fallback;
|
|
201
|
+
$[26] = t6;
|
|
202
|
+
$[27] = t7;
|
|
203
|
+
} else t7 = $[27];
|
|
204
|
+
let t8;
|
|
205
|
+
if ($[28] !== input || $[29] !== t7) {
|
|
206
|
+
t8 = /* @__PURE__ */ jsx(RuntimeChrome, {
|
|
207
|
+
input,
|
|
208
|
+
children: t7
|
|
144
209
|
});
|
|
145
|
-
$[
|
|
146
|
-
$[
|
|
147
|
-
$[
|
|
148
|
-
} else
|
|
149
|
-
return
|
|
210
|
+
$[28] = input;
|
|
211
|
+
$[29] = t7;
|
|
212
|
+
$[30] = t8;
|
|
213
|
+
} else t8 = $[30];
|
|
214
|
+
return t8;
|
|
150
215
|
}
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
$[
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
216
|
+
if (input.routeKind) return null;
|
|
217
|
+
if (hasHydrated && isLocalhostPreview()) {
|
|
218
|
+
let t5;
|
|
219
|
+
if ($[31] !== published) {
|
|
220
|
+
t5 = /* @__PURE__ */ jsx(LazyLocalhostPreviewProvider, { children: published });
|
|
221
|
+
$[31] = published;
|
|
222
|
+
$[32] = t5;
|
|
223
|
+
} else t5 = $[32];
|
|
224
|
+
let t6;
|
|
225
|
+
if ($[33] !== published || $[34] !== t5) {
|
|
226
|
+
t6 = /* @__PURE__ */ jsx(React.Suspense, {
|
|
161
227
|
fallback: published,
|
|
162
|
-
children:
|
|
228
|
+
children: t5
|
|
163
229
|
});
|
|
164
|
-
$[
|
|
165
|
-
$[
|
|
166
|
-
$[
|
|
167
|
-
} else
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
230
|
+
$[33] = published;
|
|
231
|
+
$[34] = t5;
|
|
232
|
+
$[35] = t6;
|
|
233
|
+
} else t6 = $[35];
|
|
234
|
+
return t6;
|
|
235
|
+
}
|
|
236
|
+
if (studioDocument) {
|
|
237
|
+
let t5;
|
|
238
|
+
if ($[36] === Symbol.for("react.memo_cache_sentinel")) {
|
|
239
|
+
t5 = { height: "100vh" };
|
|
240
|
+
$[36] = t5;
|
|
241
|
+
} else t5 = $[36];
|
|
242
|
+
let t6;
|
|
243
|
+
if ($[37] !== isolatedPage) {
|
|
244
|
+
t6 = /* @__PURE__ */ jsx("div", {
|
|
245
|
+
style: t5,
|
|
246
|
+
children: isolatedPage
|
|
173
247
|
});
|
|
174
|
-
$[
|
|
175
|
-
$[
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
return t4;
|
|
248
|
+
$[37] = isolatedPage;
|
|
249
|
+
$[38] = t6;
|
|
250
|
+
} else t6 = $[38];
|
|
251
|
+
return t6;
|
|
179
252
|
}
|
|
180
253
|
return published;
|
|
181
254
|
}
|
|
255
|
+
function _temp2() {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
182
258
|
function _temp() {
|
|
183
|
-
|
|
184
|
-
return new URL(window.location.href).searchParams.has("ott");
|
|
259
|
+
return true;
|
|
185
260
|
}
|
|
186
261
|
|
|
187
262
|
//#endregion
|
|
@@ -1,168 +1,117 @@
|
|
|
1
1
|
import { NavigationProvider } from "../navigation/navigation.js";
|
|
2
2
|
import { createPageHeadInput } from "./runtime.js";
|
|
3
|
+
import { createNavigationRequestTracker } from "./navigationRequest.js";
|
|
4
|
+
import { getNavigationTarget, runtimePath } from "./navigationTarget.js";
|
|
3
5
|
import { hydrate } from "@tanstack/react-query";
|
|
4
6
|
import * as React from "react";
|
|
5
7
|
import { jsx } from "react/jsx-runtime";
|
|
6
8
|
import { createHead, renderDOMHead } from "@unhead/react/client";
|
|
7
9
|
|
|
8
10
|
//#region src/features/runtime/pageNavigation.tsx
|
|
9
|
-
function
|
|
10
|
-
if (!
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
function normalizePagePath(pathname, runtimeBasePath) {
|
|
14
|
-
const basePath = normalizeRuntimeBasePath(runtimeBasePath);
|
|
15
|
-
if (!basePath) return pathname || "/";
|
|
16
|
-
if (pathname === basePath) return "/";
|
|
17
|
-
if (pathname.startsWith(`${basePath}/`)) return pathname.slice(basePath.length) || "/";
|
|
18
|
-
return pathname || "/";
|
|
19
|
-
}
|
|
20
|
-
function toRuntimePathname(pagePathname, runtimeBasePath) {
|
|
21
|
-
const basePath = normalizeRuntimeBasePath(runtimeBasePath);
|
|
22
|
-
const normalizedPathname = pagePathname.startsWith("/") ? pagePathname : `/${pagePathname}`;
|
|
23
|
-
if (!basePath) return normalizedPathname;
|
|
24
|
-
if (normalizedPathname === "/") return `${basePath}/`;
|
|
25
|
-
if (normalizedPathname.startsWith(`${basePath}/`)) return normalizedPathname;
|
|
26
|
-
return `${basePath}${normalizedPathname}`;
|
|
27
|
-
}
|
|
28
|
-
function getRuntimeLocation(runtimeBasePath) {
|
|
29
|
-
return {
|
|
30
|
-
hash: window.location.hash,
|
|
31
|
-
href: window.location.href,
|
|
32
|
-
pathname: normalizePagePath(window.location.pathname, runtimeBasePath),
|
|
33
|
-
search: window.location.search
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
function isReservedPagePath(pathname) {
|
|
37
|
-
return pathname.startsWith("/_camox/") || pathname === "/_camox" || pathname === "/camox" || pathname.startsWith("/camox/") || pathname === "/og" || pathname === "/sitemap.xml";
|
|
38
|
-
}
|
|
39
|
-
function getClientNavigationTarget(to, runtimeBasePath) {
|
|
40
|
-
const url = new URL(to, window.location.href);
|
|
41
|
-
if (url.origin !== window.location.origin) return null;
|
|
42
|
-
const pagePathname = normalizePagePath(url.pathname, runtimeBasePath);
|
|
43
|
-
if (isReservedPagePath(pagePathname)) return null;
|
|
44
|
-
url.pathname = toRuntimePathname(pagePathname, runtimeBasePath);
|
|
45
|
-
return url;
|
|
46
|
-
}
|
|
47
|
-
async function fetchPageData(pagePathname, runtimeBasePath) {
|
|
48
|
-
const dataUrl = new URL(toRuntimePathname("/_camox/data", runtimeBasePath), window.location.origin);
|
|
49
|
-
dataUrl.searchParams.set("path", pagePathname);
|
|
50
|
-
const response = await fetch(dataUrl, {
|
|
51
|
-
headers: { Accept: "application/json" },
|
|
52
|
-
credentials: "same-origin"
|
|
53
|
-
});
|
|
54
|
-
if (!response.ok) throw new Error(`Page data request failed: ${response.status}`);
|
|
55
|
-
return await response.json();
|
|
56
|
-
}
|
|
57
|
-
function isPageHead(head) {
|
|
58
|
-
return !!head && typeof head === "object";
|
|
59
|
-
}
|
|
60
|
-
function updateHead(head, manager) {
|
|
61
|
-
if (!isPageHead(head)) return;
|
|
62
|
-
if (!manager.removedServerPageHead) {
|
|
63
|
-
document.querySelectorAll("[data-camox-page-head]").forEach((element) => element.remove());
|
|
64
|
-
manager.removedServerPageHead = true;
|
|
65
|
-
}
|
|
66
|
-
manager.entry?.dispose();
|
|
67
|
-
manager.entry = manager.head.push(createPageHeadInput(head));
|
|
68
|
-
renderDOMHead(manager.head);
|
|
69
|
-
}
|
|
70
|
-
function hasSameLayoutIdentity(current, next) {
|
|
71
|
-
return !!current && !!next && current.id === next.id && current.layoutId === next.layoutId && current.version === next.version;
|
|
72
|
-
}
|
|
73
|
-
function isLayoutBlockQuery(query, layoutBlockIds) {
|
|
74
|
-
if (!query || typeof query !== "object") return false;
|
|
75
|
-
const queryKey = query.queryKey;
|
|
76
|
-
return Array.isArray(queryKey) && queryKey[0] === "camox" && queryKey[1] === "blocks" && queryKey[2] === "get" && typeof queryKey[3] === "number" && layoutBlockIds.has(queryKey[3]);
|
|
77
|
-
}
|
|
78
|
-
function preserveStableLayoutBlockCaches(dehydratedState, currentLayout, nextLayout) {
|
|
79
|
-
if (!hasSameLayoutIdentity(currentLayout, nextLayout)) return dehydratedState;
|
|
80
|
-
if (!dehydratedState || typeof dehydratedState !== "object") return dehydratedState;
|
|
81
|
-
if (!Array.isArray(dehydratedState.queries)) return dehydratedState;
|
|
82
|
-
const layoutBlockIds = new Set(currentLayout?.blockIds ?? []);
|
|
11
|
+
function preserveStableLayoutBlockCaches(dehydratedState, current, next) {
|
|
12
|
+
if (!current || !next || current.id !== next.id || current.layoutId !== next.layoutId || current.version !== next.version) return dehydratedState;
|
|
13
|
+
if (!dehydratedState || typeof dehydratedState !== "object" || !("queries" in dehydratedState) || !Array.isArray(dehydratedState.queries)) return dehydratedState;
|
|
14
|
+
const ids = new Set(current.blockIds);
|
|
83
15
|
return {
|
|
84
16
|
...dehydratedState,
|
|
85
|
-
queries: dehydratedState.queries.filter((query) =>
|
|
17
|
+
queries: dehydratedState.queries.filter((query) => {
|
|
18
|
+
const key = query.queryKey;
|
|
19
|
+
return !(key?.[0] === "camox" && key[1] === "blocks" && key[2] === "get" && typeof key[3] === "number" && ids.has(key[3]));
|
|
20
|
+
})
|
|
86
21
|
};
|
|
87
22
|
}
|
|
88
23
|
function PageNavigationProvider({ children, initialInput, queryClient }) {
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const navigate = React.useCallback(async ({ replace, to }) => {
|
|
97
|
-
const target = getClientNavigationTarget(to, initialInput.runtimeBasePath);
|
|
24
|
+
const [input, setInput] = React.useState(initialInput);
|
|
25
|
+
const current = React.useRef(initialInput);
|
|
26
|
+
const [requests] = React.useState(createNavigationRequestTracker);
|
|
27
|
+
const headManager = React.useRef(null);
|
|
28
|
+
const navigate = React.useCallback(async ({ to, replace, pop = false }) => {
|
|
29
|
+
const request = requests.begin();
|
|
30
|
+
const target = getNavigationTarget(to, window.location.href, initialInput.runtimeBasePath);
|
|
98
31
|
if (!target) {
|
|
99
|
-
window.location.
|
|
32
|
+
if (replace) window.location.replace(to);
|
|
33
|
+
else window.location.assign(to);
|
|
100
34
|
return;
|
|
101
35
|
}
|
|
102
|
-
const pagePathname = normalizePagePath(target.pathname, initialInput.runtimeBasePath);
|
|
103
36
|
try {
|
|
104
|
-
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
|
|
37
|
+
let next = current.current;
|
|
38
|
+
if (target.pathname !== next.pathname || pop) {
|
|
39
|
+
const url = new URL(runtimePath("/_camox/data", initialInput.runtimeBasePath), window.location.origin);
|
|
40
|
+
url.searchParams.set("path", target.pathname);
|
|
41
|
+
const response = await fetch(url, {
|
|
42
|
+
credentials: "same-origin",
|
|
43
|
+
headers: { Accept: "application/json" },
|
|
44
|
+
signal: request.signal
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok) throw new Error(`Navigation failed: ${response.status}`);
|
|
47
|
+
next = await response.json();
|
|
48
|
+
if (next.pathname !== target.pathname || !next.dehydratedState) throw new Error("Invalid navigation response");
|
|
49
|
+
}
|
|
50
|
+
if (!request.isCurrent()) return;
|
|
51
|
+
hydrate(queryClient, preserveStableLayoutBlockCaches(next.dehydratedState, current.current.layoutIdentity, next.layoutIdentity));
|
|
52
|
+
next = {
|
|
53
|
+
...next,
|
|
54
|
+
href: target.url.href
|
|
55
|
+
};
|
|
56
|
+
current.current = next;
|
|
57
|
+
if (!pop) if (replace) window.history.replaceState(null, "", target.url.href);
|
|
58
|
+
else window.history.pushState(null, "", target.url.href);
|
|
59
|
+
if (!headManager.current) {
|
|
60
|
+
document.querySelectorAll("[data-camox-page-head]").forEach((element) => element.remove());
|
|
61
|
+
headManager.current = { head: createHead() };
|
|
62
|
+
}
|
|
63
|
+
const manager = headManager.current;
|
|
64
|
+
manager.entry?.dispose();
|
|
65
|
+
manager.entry = manager.head.push(createPageHeadInput(next.head ?? {}));
|
|
66
|
+
renderDOMHead(manager.head);
|
|
67
|
+
React.startTransition(() => setInput(next));
|
|
68
|
+
if (!pop && !replace && !target.url.hash) window.scrollTo({ top: 0 });
|
|
108
69
|
} catch {
|
|
109
|
-
|
|
110
|
-
|
|
70
|
+
if (!request.isCurrent()) return;
|
|
71
|
+
if (pop) window.location.reload();
|
|
72
|
+
else if (replace) window.location.replace(target.url.href);
|
|
73
|
+
else window.location.assign(target.url.href);
|
|
111
74
|
}
|
|
112
|
-
if (replace) window.history.replaceState(null, "", target.href);
|
|
113
|
-
else {
|
|
114
|
-
window.history.pushState(null, "", target.href);
|
|
115
|
-
window.scrollTo({ top: 0 });
|
|
116
|
-
}
|
|
117
|
-
window.dispatchEvent(new Event("camox:navigation"));
|
|
118
75
|
}, [
|
|
119
|
-
headManager,
|
|
120
76
|
initialInput.runtimeBasePath,
|
|
121
|
-
queryClient
|
|
77
|
+
queryClient,
|
|
78
|
+
requests
|
|
122
79
|
]);
|
|
123
80
|
React.useEffect(() => {
|
|
124
81
|
const onClick = (event) => {
|
|
125
|
-
if (event.defaultPrevented) return;
|
|
126
|
-
if (event.button !== 0) return;
|
|
127
|
-
if (event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) return;
|
|
82
|
+
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
|
|
128
83
|
const anchor = event.target?.closest("a");
|
|
129
|
-
if (!anchor) return;
|
|
130
|
-
if (anchor.
|
|
131
|
-
if (anchor.target && anchor.target !== "_self") return;
|
|
132
|
-
const target_0 = getClientNavigationTarget(anchor.href, initialInput.runtimeBasePath);
|
|
133
|
-
if (!target_0) return;
|
|
84
|
+
if (!anchor || anchor.hasAttribute("download") || anchor.target && anchor.target !== "_self") return;
|
|
85
|
+
if (!getNavigationTarget(anchor.href, window.location.href, initialInput.runtimeBasePath)) return;
|
|
134
86
|
event.preventDefault();
|
|
135
|
-
navigate({ to:
|
|
87
|
+
navigate({ to: anchor.href });
|
|
136
88
|
};
|
|
89
|
+
const onPopState = () => void navigate({
|
|
90
|
+
to: window.location.href,
|
|
91
|
+
pop: true
|
|
92
|
+
});
|
|
137
93
|
document.addEventListener("click", onClick);
|
|
138
|
-
return () => document.removeEventListener("click", onClick);
|
|
139
|
-
}, [navigate]);
|
|
140
|
-
React.useEffect(() => {
|
|
141
|
-
const onPopState = () => {
|
|
142
|
-
fetchPageData(normalizePagePath(window.location.pathname, initialInput.runtimeBasePath), initialInput.runtimeBasePath).then((data_0) => {
|
|
143
|
-
if (data_0.dehydratedState) hydrate(queryClient, preserveStableLayoutBlockCaches(data_0.dehydratedState, currentLayoutIdentityRef.current, data_0.layoutIdentity));
|
|
144
|
-
currentLayoutIdentityRef.current = data_0.layoutIdentity ?? null;
|
|
145
|
-
updateHead(data_0.head, headManager);
|
|
146
|
-
window.dispatchEvent(new Event("camox:navigation"));
|
|
147
|
-
}).catch(() => window.location.reload());
|
|
148
|
-
};
|
|
149
94
|
window.addEventListener("popstate", onPopState);
|
|
150
|
-
return () =>
|
|
95
|
+
return () => {
|
|
96
|
+
document.removeEventListener("click", onClick);
|
|
97
|
+
window.removeEventListener("popstate", onPopState);
|
|
98
|
+
requests.cancel();
|
|
99
|
+
};
|
|
151
100
|
}, [
|
|
152
|
-
|
|
101
|
+
navigate,
|
|
153
102
|
initialInput.runtimeBasePath,
|
|
154
|
-
|
|
103
|
+
requests
|
|
155
104
|
]);
|
|
105
|
+
const url_0 = new URL(input.href);
|
|
156
106
|
return /* @__PURE__ */ jsx(NavigationProvider, {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
search: new URL(initialInput.href).search
|
|
107
|
+
location: {
|
|
108
|
+
href: input.href,
|
|
109
|
+
pathname: input.pathname,
|
|
110
|
+
hash: url_0.hash,
|
|
111
|
+
search: url_0.search
|
|
163
112
|
},
|
|
164
113
|
navigate,
|
|
165
|
-
children
|
|
114
|
+
children: children(input)
|
|
166
115
|
});
|
|
167
116
|
}
|
|
168
117
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CamoxApp } from "../../core/createApp.js";
|
|
2
2
|
import { CamoxDocument } from "../../core/defineDocument.js";
|
|
3
|
+
import { createServerApiClient } from "../routes/pageRuntime.js";
|
|
3
4
|
import { StudioRenderInput } from "./studioApp.js";
|
|
4
5
|
import { UseHeadInput } from "unhead/types";
|
|
5
6
|
|
|
@@ -16,6 +17,15 @@ interface LayoutIdentity {
|
|
|
16
17
|
version: string;
|
|
17
18
|
}
|
|
18
19
|
interface PageRenderInput {
|
|
20
|
+
previewDocument?: string;
|
|
21
|
+
routeKind?: "studio" | "studio-content" | "studio-nested";
|
|
22
|
+
project?: Awaited<ReturnType<ReturnType<typeof createServerApiClient>["projects"]["getBySlug"]>>;
|
|
23
|
+
presentation?: "public" | "studio";
|
|
24
|
+
derived?: {
|
|
25
|
+
layoutId: string;
|
|
26
|
+
data: unknown;
|
|
27
|
+
layout: Awaited<ReturnType<ReturnType<typeof createServerApiClient>["layouts"]["get"]>>["layout"];
|
|
28
|
+
};
|
|
19
29
|
apiUrl: string;
|
|
20
30
|
authenticationUrl: string;
|
|
21
31
|
dehydratedState: unknown;
|
|
@@ -42,6 +52,7 @@ interface RuntimeOptions {
|
|
|
42
52
|
renderStudio?: (input: StudioRenderInput) => Promise<string>;
|
|
43
53
|
runtimeBasePath?: string;
|
|
44
54
|
stylesheetUrl?: string;
|
|
55
|
+
studioStylesheetUrl?: string;
|
|
45
56
|
}
|
|
46
57
|
declare function getRuntimePathname(url: string, runtimeBasePath?: string): string | null;
|
|
47
58
|
declare function matchRuntimeRoute(pathname: string): RuntimeRouteMatch;
|