camox 0.33.0 → 0.34.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/components/AuthGate.js +5 -4
- package/dist/core/createBlock.js +19 -19
- package/dist/core/defineDocument.d.ts +7 -0
- package/dist/core/defineDocument.js +7 -0
- package/dist/features/agent-chat/components/AgentChatSidebar.js +3 -3
- package/dist/features/agent-chat/components/AgentChatThread.js +10 -11
- package/dist/features/navigation/navigation.d.ts +39 -0
- package/dist/features/navigation/navigation.js +231 -0
- package/dist/features/preview/CamoxPreview.d.ts +3 -0
- package/dist/features/preview/CamoxPreview.js +12 -12
- package/dist/features/preview/components/AddBlockSidebar.js +4 -4
- package/dist/features/preview/components/AssetLightbox.js +10 -9
- package/dist/features/preview/components/CreatePageModal.js +3 -3
- package/dist/features/preview/components/FieldToolbar.js +1 -1
- package/dist/features/preview/components/PageInfoSidebar.js +23 -23
- package/dist/features/preview/components/PageNavigatorSidebar.js +6 -6
- package/dist/features/preview/components/PagePicker.js +1 -1
- package/dist/features/preview/components/PreviewToolbar.js +3 -3
- package/dist/features/preview/components/useUpdateBlockPosition.js +3 -3
- package/dist/features/provider/CamoxProvider.js +10 -8
- package/dist/features/routes/pageRuntime.js +6 -0
- package/dist/features/runtime/pageApp.js +75 -0
- package/dist/features/runtime/pageClient.d.ts +7 -0
- package/dist/features/runtime/pageClient.js +37 -0
- package/dist/features/runtime/pageNavigation.js +170 -0
- package/dist/features/runtime/pageServer.d.ts +9 -0
- package/dist/features/runtime/pageServer.js +18 -0
- package/dist/features/runtime/runtime.d.ts +24 -0
- package/dist/features/runtime/runtime.js +44 -0
- package/dist/features/runtime/studioApp.d.ts +15 -0
- package/dist/features/runtime/studioApp.js +117 -0
- package/dist/features/runtime/studioNavigation.js +115 -0
- package/dist/features/runtime/studioServer.d.ts +9 -0
- package/dist/features/runtime/studioServer.js +18 -0
- package/dist/features/studio/CamoxStudio.js +3 -3
- package/dist/features/studio/components/Navbar.js +7 -7
- package/dist/features/studio/components/ProjectMenu.js +9 -9
- package/dist/features/studio/components/UserButton.js +3 -3
- package/dist/features/vite/appGeneration.js +16 -5
- package/dist/features/vite/blockBoilerplate.js +1 -1
- package/dist/features/vite/definitionsSync.js +4 -4
- package/dist/features/vite/routeGeneration.js +9 -156
- package/dist/features/vite/runtimeDev.js +270 -0
- package/dist/features/vite/utils.js +3 -1
- package/dist/features/vite/vite.d.ts +22 -3
- package/dist/features/vite/vite.js +36 -19
- package/dist/hooks/use-file-upload.js +3 -1
- package/dist/lib/api-client.js +6 -3
- package/dist/lib/auth.js +45 -68
- package/dist/lib/queries.js +6 -4
- package/dist/lib/telemetry.js +1 -24
- package/dist/lib/utils.js +1 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/Matches.d.ts +114 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/RouterProvider.d.ts +25 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/config.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/defer.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/fileRoute.d.ts +20 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/global.d.ts +8 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/hash-scroll.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/index.d.ts +18 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/link.d.ts +161 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/load-matches.d.ts +6 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/location.d.ts +54 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/lru-cache.d.ts +8 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/manifest.d.ts +32 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/new-process-route-tree.d.ts +115 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/not-found.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/redirect.d.ts +49 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/rewrite.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/root.d.ts +6 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/route.d.ts +343 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/routeInfo.d.ts +48 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/router.d.ts +695 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/scroll-restoration.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchMiddleware.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchParams.d.ts +5 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/RawStream.d.ts +38 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/seroval-plugins.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/transformer.d.ts +65 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/stores.d.ts +69 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/structuralSharing.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/typePrimitives.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderData.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderDeps.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useNavigate.d.ts +10 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useParams.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useRouteContext.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useSearch.d.ts +1 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/utils.d.ts +28 -0
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/validators.d.ts +49 -0
- package/package.json +34 -12
- package/skills/camox-block/SKILL.md +4 -4
- package/skills/camox-cli/SKILL.md +3 -3
- package/skills/camox-layout/SKILL.md +2 -2
- package/dist/features/routes/ogRoute.d.ts +0 -12
- package/dist/features/routes/ogRoute.js +0 -20
- package/dist/features/routes/pageRoute.d.ts +0 -48
- package/dist/features/routes/pageRoute.js +0 -254
- package/dist/lib/api-client.d.ts +0 -7
- package/dist/lib/queries.d.ts +0 -12
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { NavigationProvider } from "../navigation/navigation.js";
|
|
2
|
+
import { createPageHeadInput } from "./runtime.js";
|
|
3
|
+
import { hydrate } from "@tanstack/react-query";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
import { createHead, renderDOMHead } from "@unhead/react/client";
|
|
7
|
+
|
|
8
|
+
//#region src/features/runtime/pageNavigation.tsx
|
|
9
|
+
function normalizeRuntimeBasePath(basePath) {
|
|
10
|
+
if (!basePath || basePath === "/") return "";
|
|
11
|
+
return basePath.startsWith("/") ? basePath.replace(/\/+$/, "") : `/${basePath.replace(/\/+$/, "")}`;
|
|
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 ?? []);
|
|
83
|
+
return {
|
|
84
|
+
...dehydratedState,
|
|
85
|
+
queries: dehydratedState.queries.filter((query) => !isLayoutBlockQuery(query, layoutBlockIds))
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function PageNavigationProvider({ children, initialInput, queryClient }) {
|
|
89
|
+
const headManagerRef = React.useRef(null);
|
|
90
|
+
if (!headManagerRef.current) headManagerRef.current = {
|
|
91
|
+
head: createHead(),
|
|
92
|
+
removedServerPageHead: false
|
|
93
|
+
};
|
|
94
|
+
const headManager = headManagerRef.current;
|
|
95
|
+
const currentLayoutIdentityRef = React.useRef(initialInput.layoutIdentity);
|
|
96
|
+
const navigate = React.useCallback(async ({ replace, to }) => {
|
|
97
|
+
const target = getClientNavigationTarget(to, initialInput.runtimeBasePath);
|
|
98
|
+
if (!target) {
|
|
99
|
+
window.location.assign(to);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const pagePathname = normalizePagePath(target.pathname, initialInput.runtimeBasePath);
|
|
103
|
+
try {
|
|
104
|
+
const data = await fetchPageData(pagePathname, initialInput.runtimeBasePath);
|
|
105
|
+
if (data.dehydratedState) hydrate(queryClient, preserveStableLayoutBlockCaches(data.dehydratedState, currentLayoutIdentityRef.current, data.layoutIdentity));
|
|
106
|
+
currentLayoutIdentityRef.current = data.layoutIdentity ?? null;
|
|
107
|
+
updateHead(data.head, headManager);
|
|
108
|
+
} catch {
|
|
109
|
+
window.location.assign(target.href);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
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
|
+
}, [
|
|
119
|
+
headManager,
|
|
120
|
+
initialInput.runtimeBasePath,
|
|
121
|
+
queryClient
|
|
122
|
+
]);
|
|
123
|
+
React.useEffect(() => {
|
|
124
|
+
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;
|
|
128
|
+
const anchor = event.target?.closest("a");
|
|
129
|
+
if (!anchor) return;
|
|
130
|
+
if (anchor.hasAttribute("download")) return;
|
|
131
|
+
if (anchor.target && anchor.target !== "_self") return;
|
|
132
|
+
const target_0 = getClientNavigationTarget(anchor.href, initialInput.runtimeBasePath);
|
|
133
|
+
if (!target_0) return;
|
|
134
|
+
event.preventDefault();
|
|
135
|
+
navigate({ to: target_0.href });
|
|
136
|
+
};
|
|
137
|
+
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
|
+
window.addEventListener("popstate", onPopState);
|
|
150
|
+
return () => window.removeEventListener("popstate", onPopState);
|
|
151
|
+
}, [
|
|
152
|
+
headManager,
|
|
153
|
+
initialInput.runtimeBasePath,
|
|
154
|
+
queryClient
|
|
155
|
+
]);
|
|
156
|
+
return /* @__PURE__ */ jsx(NavigationProvider, {
|
|
157
|
+
getLocation: React.useCallback(() => getRuntimeLocation(initialInput.runtimeBasePath), [initialInput.runtimeBasePath]),
|
|
158
|
+
initialLocation: {
|
|
159
|
+
hash: new URL(initialInput.href).hash,
|
|
160
|
+
href: initialInput.href,
|
|
161
|
+
pathname: initialInput.pathname,
|
|
162
|
+
search: new URL(initialInput.href).search
|
|
163
|
+
},
|
|
164
|
+
navigate,
|
|
165
|
+
children
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
//#endregion
|
|
170
|
+
export { PageNavigationProvider };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CamoxApp } from "../../core/createApp.js";
|
|
2
|
+
import { PageRenderInput } from "./runtime.js";
|
|
3
|
+
|
|
4
|
+
//#region src/features/runtime/pageServer.d.ts
|
|
5
|
+
declare function renderPageWithApp(input: PageRenderInput & {
|
|
6
|
+
camoxApp: CamoxApp;
|
|
7
|
+
}): Promise<string>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { renderPageWithApp };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PageApp } from "./pageApp.js";
|
|
2
|
+
import { QueryClient, hydrate } from "@tanstack/react-query";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { renderToString } from "react-dom/server";
|
|
5
|
+
|
|
6
|
+
//#region src/features/runtime/pageServer.tsx
|
|
7
|
+
async function renderPageWithApp(input) {
|
|
8
|
+
const queryClient = new QueryClient();
|
|
9
|
+
hydrate(queryClient, input.dehydratedState);
|
|
10
|
+
return renderToString(/* @__PURE__ */ jsx(PageApp, {
|
|
11
|
+
camoxApp: input.camoxApp,
|
|
12
|
+
input,
|
|
13
|
+
queryClient
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { renderPageWithApp };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { UseHeadInput } from "unhead/types";
|
|
2
|
+
|
|
3
|
+
//#region src/features/runtime/runtime.d.ts
|
|
4
|
+
interface LayoutIdentity {
|
|
5
|
+
blockIds: number[];
|
|
6
|
+
id: number;
|
|
7
|
+
layoutId: string;
|
|
8
|
+
version: string;
|
|
9
|
+
}
|
|
10
|
+
interface PageRenderInput {
|
|
11
|
+
apiUrl: string;
|
|
12
|
+
authenticationUrl: string;
|
|
13
|
+
dehydratedState: unknown;
|
|
14
|
+
environmentName?: string;
|
|
15
|
+
head: unknown;
|
|
16
|
+
href: string;
|
|
17
|
+
layoutIdentity: LayoutIdentity | null;
|
|
18
|
+
loaderData: unknown;
|
|
19
|
+
pathname: string;
|
|
20
|
+
projectSlug: string;
|
|
21
|
+
runtimeBasePath: string;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { PageRenderInput };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import "../routes/pageRuntime.js";
|
|
2
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
3
|
+
import "@unhead/react/server";
|
|
4
|
+
|
|
5
|
+
//#region src/features/runtime/runtime.ts
|
|
6
|
+
function createPageHeadInput(head) {
|
|
7
|
+
const meta = head.meta ?? [];
|
|
8
|
+
const links = head.links ?? [];
|
|
9
|
+
const title = meta.find((entry) => entry.title)?.title;
|
|
10
|
+
const pageMeta = [];
|
|
11
|
+
for (const entry of meta) {
|
|
12
|
+
if (entry.title) continue;
|
|
13
|
+
if (entry.name && entry.content) {
|
|
14
|
+
pageMeta.push({
|
|
15
|
+
name: entry.name,
|
|
16
|
+
content: entry.content,
|
|
17
|
+
"data-camox-page-head": "true"
|
|
18
|
+
});
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (entry.property && entry.content) pageMeta.push({
|
|
22
|
+
property: entry.property,
|
|
23
|
+
content: entry.content,
|
|
24
|
+
"data-camox-page-head": "true"
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const pageLinks = [];
|
|
28
|
+
for (const entry of links) {
|
|
29
|
+
if (entry.rel !== "icon" || !entry.href) continue;
|
|
30
|
+
pageLinks.push({
|
|
31
|
+
rel: "icon",
|
|
32
|
+
href: entry.href,
|
|
33
|
+
"data-camox-page-head": "true"
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
...title && { title },
|
|
38
|
+
meta: pageMeta,
|
|
39
|
+
link: pageLinks
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { createPageHeadInput };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
2
|
+
//#region src/features/runtime/studioApp.d.ts
|
|
3
|
+
interface StudioRenderInput {
|
|
4
|
+
apiUrl: string;
|
|
5
|
+
authenticationUrl: string;
|
|
6
|
+
dehydratedState: unknown;
|
|
7
|
+
environmentName?: string;
|
|
8
|
+
href: string;
|
|
9
|
+
pathname: string;
|
|
10
|
+
projectSlug: string;
|
|
11
|
+
routeKind: "studio" | "studio-content" | "studio-nested";
|
|
12
|
+
runtimeBasePath: string;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { StudioRenderInput };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { STUDIO_CONTENT_PATH } from "../studio/routes.js";
|
|
2
|
+
import { CamoxContent } from "../content/CamoxContent.js";
|
|
3
|
+
import { CamoxProvider } from "../provider/CamoxProvider.js";
|
|
4
|
+
import { CamoxStudio } from "../studio/CamoxStudio.js";
|
|
5
|
+
import { StudioNavigationProvider } from "./studioNavigation.js";
|
|
6
|
+
import { c } from "react/compiler-runtime";
|
|
7
|
+
import { HydrationBoundary, QueryClientProvider } from "@tanstack/react-query";
|
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
|
9
|
+
|
|
10
|
+
//#region src/features/runtime/studioApp.tsx
|
|
11
|
+
function StudioRouteContent(t0) {
|
|
12
|
+
const $ = c(4);
|
|
13
|
+
if ($[0] !== "4c7f5ba34e144c65d886d3b5a39ff5adc9765123d3c37bd6491f55534f919b1f") {
|
|
14
|
+
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
15
|
+
$[0] = "4c7f5ba34e144c65d886d3b5a39ff5adc9765123d3c37bd6491f55534f919b1f";
|
|
16
|
+
}
|
|
17
|
+
const { input } = t0;
|
|
18
|
+
if (input.pathname === STUDIO_CONTENT_PATH) {
|
|
19
|
+
let t1;
|
|
20
|
+
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
|
21
|
+
t1 = /* @__PURE__ */ jsx(CamoxContent, {});
|
|
22
|
+
$[1] = t1;
|
|
23
|
+
} else t1 = $[1];
|
|
24
|
+
return t1;
|
|
25
|
+
}
|
|
26
|
+
if (input.routeKind === "studio-nested") {
|
|
27
|
+
let t1;
|
|
28
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
29
|
+
t1 = /* @__PURE__ */ jsx("div", {
|
|
30
|
+
className: "text-muted-foreground p-6 text-sm",
|
|
31
|
+
children: "Studio page not found"
|
|
32
|
+
});
|
|
33
|
+
$[2] = t1;
|
|
34
|
+
} else t1 = $[2];
|
|
35
|
+
return t1;
|
|
36
|
+
}
|
|
37
|
+
let t1;
|
|
38
|
+
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
|
39
|
+
t1 = /* @__PURE__ */ jsx("div", {
|
|
40
|
+
className: "text-muted-foreground p-6 text-sm",
|
|
41
|
+
children: "Loading Studio…"
|
|
42
|
+
});
|
|
43
|
+
$[3] = t1;
|
|
44
|
+
} else t1 = $[3];
|
|
45
|
+
return t1;
|
|
46
|
+
}
|
|
47
|
+
function StudioApp(t0) {
|
|
48
|
+
const $ = c(21);
|
|
49
|
+
if ($[0] !== "4c7f5ba34e144c65d886d3b5a39ff5adc9765123d3c37bd6491f55534f919b1f") {
|
|
50
|
+
for (let $i = 0; $i < 21; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
51
|
+
$[0] = "4c7f5ba34e144c65d886d3b5a39ff5adc9765123d3c37bd6491f55534f919b1f";
|
|
52
|
+
}
|
|
53
|
+
const { camoxApp, input, queryClient } = t0;
|
|
54
|
+
const t1 = input.dehydratedState;
|
|
55
|
+
let t2;
|
|
56
|
+
if ($[1] !== input) {
|
|
57
|
+
t2 = /* @__PURE__ */ jsx(CamoxStudio, { children: /* @__PURE__ */ jsx(StudioRouteContent, { input }) });
|
|
58
|
+
$[1] = input;
|
|
59
|
+
$[2] = t2;
|
|
60
|
+
} else t2 = $[2];
|
|
61
|
+
let t3;
|
|
62
|
+
if ($[3] !== camoxApp || $[4] !== input.apiUrl || $[5] !== input.authenticationUrl || $[6] !== input.environmentName || $[7] !== input.projectSlug || $[8] !== t2) {
|
|
63
|
+
t3 = /* @__PURE__ */ jsx(CamoxProvider, {
|
|
64
|
+
camoxApp,
|
|
65
|
+
authenticationUrl: input.authenticationUrl,
|
|
66
|
+
apiUrl: input.apiUrl,
|
|
67
|
+
projectSlug: input.projectSlug,
|
|
68
|
+
environmentName: input.environmentName,
|
|
69
|
+
children: t2
|
|
70
|
+
});
|
|
71
|
+
$[3] = camoxApp;
|
|
72
|
+
$[4] = input.apiUrl;
|
|
73
|
+
$[5] = input.authenticationUrl;
|
|
74
|
+
$[6] = input.environmentName;
|
|
75
|
+
$[7] = input.projectSlug;
|
|
76
|
+
$[8] = t2;
|
|
77
|
+
$[9] = t3;
|
|
78
|
+
} else t3 = $[9];
|
|
79
|
+
let t4;
|
|
80
|
+
if ($[10] !== input.href || $[11] !== input.pathname || $[12] !== input.runtimeBasePath || $[13] !== t3) {
|
|
81
|
+
t4 = /* @__PURE__ */ jsx(StudioNavigationProvider, {
|
|
82
|
+
href: input.href,
|
|
83
|
+
pathname: input.pathname,
|
|
84
|
+
runtimeBasePath: input.runtimeBasePath,
|
|
85
|
+
children: t3
|
|
86
|
+
});
|
|
87
|
+
$[10] = input.href;
|
|
88
|
+
$[11] = input.pathname;
|
|
89
|
+
$[12] = input.runtimeBasePath;
|
|
90
|
+
$[13] = t3;
|
|
91
|
+
$[14] = t4;
|
|
92
|
+
} else t4 = $[14];
|
|
93
|
+
let t5;
|
|
94
|
+
if ($[15] !== t1 || $[16] !== t4) {
|
|
95
|
+
t5 = /* @__PURE__ */ jsx(HydrationBoundary, {
|
|
96
|
+
state: t1,
|
|
97
|
+
children: t4
|
|
98
|
+
});
|
|
99
|
+
$[15] = t1;
|
|
100
|
+
$[16] = t4;
|
|
101
|
+
$[17] = t5;
|
|
102
|
+
} else t5 = $[17];
|
|
103
|
+
let t6;
|
|
104
|
+
if ($[18] !== queryClient || $[19] !== t5) {
|
|
105
|
+
t6 = /* @__PURE__ */ jsx(QueryClientProvider, {
|
|
106
|
+
client: queryClient,
|
|
107
|
+
children: t5
|
|
108
|
+
});
|
|
109
|
+
$[18] = queryClient;
|
|
110
|
+
$[19] = t5;
|
|
111
|
+
$[20] = t6;
|
|
112
|
+
} else t6 = $[20];
|
|
113
|
+
return t6;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
//#endregion
|
|
117
|
+
export { StudioApp };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { NavigationProvider } from "../navigation/navigation.js";
|
|
2
|
+
import { c } from "react/compiler-runtime";
|
|
3
|
+
import "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/features/runtime/studioNavigation.tsx
|
|
7
|
+
function normalizeRuntimeBasePath(basePath) {
|
|
8
|
+
if (!basePath || basePath === "/") return "";
|
|
9
|
+
return basePath.startsWith("/") ? basePath.replace(/\/+$/, "") : `/${basePath.replace(/\/+$/, "")}`;
|
|
10
|
+
}
|
|
11
|
+
function normalizeRuntimePathname(pathname, runtimeBasePath) {
|
|
12
|
+
const basePath = normalizeRuntimeBasePath(runtimeBasePath);
|
|
13
|
+
if (!basePath) return pathname || "/";
|
|
14
|
+
if (pathname === basePath) return "/";
|
|
15
|
+
if (pathname.startsWith(`${basePath}/`)) return pathname.slice(basePath.length) || "/";
|
|
16
|
+
return pathname || "/";
|
|
17
|
+
}
|
|
18
|
+
function toRuntimePathname(pathname, runtimeBasePath) {
|
|
19
|
+
const basePath = normalizeRuntimeBasePath(runtimeBasePath);
|
|
20
|
+
const normalizedPathname = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
21
|
+
if (!basePath) return normalizedPathname;
|
|
22
|
+
if (normalizedPathname === "/") return `${basePath}/`;
|
|
23
|
+
if (normalizedPathname.startsWith(`${basePath}/`)) return normalizedPathname;
|
|
24
|
+
return `${basePath}${normalizedPathname}`;
|
|
25
|
+
}
|
|
26
|
+
function getStudioLocation(runtimeBasePath) {
|
|
27
|
+
return {
|
|
28
|
+
hash: window.location.hash,
|
|
29
|
+
href: window.location.href,
|
|
30
|
+
pathname: normalizeRuntimePathname(window.location.pathname, runtimeBasePath),
|
|
31
|
+
search: window.location.search
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function getStudioTarget(to, runtimeBasePath) {
|
|
35
|
+
const url = new URL(to, window.location.href);
|
|
36
|
+
if (url.origin !== window.location.origin) return null;
|
|
37
|
+
url.pathname = toRuntimePathname(normalizeRuntimePathname(url.pathname, runtimeBasePath), runtimeBasePath);
|
|
38
|
+
return url;
|
|
39
|
+
}
|
|
40
|
+
function StudioNavigationProvider(t0) {
|
|
41
|
+
const $ = c(19);
|
|
42
|
+
if ($[0] !== "df5809d38cc8796db839fa5b8c8d05f562a3e4cba7d51a1fec989dc85db9136b") {
|
|
43
|
+
for (let $i = 0; $i < 19; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
44
|
+
$[0] = "df5809d38cc8796db839fa5b8c8d05f562a3e4cba7d51a1fec989dc85db9136b";
|
|
45
|
+
}
|
|
46
|
+
const { children, href, pathname, runtimeBasePath } = t0;
|
|
47
|
+
let t1;
|
|
48
|
+
if ($[1] !== runtimeBasePath) {
|
|
49
|
+
t1 = async (t2) => {
|
|
50
|
+
const { replace, to } = t2;
|
|
51
|
+
const target = getStudioTarget(to, runtimeBasePath);
|
|
52
|
+
if (!target) {
|
|
53
|
+
window.location.assign(to);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (replace) window.history.replaceState(null, "", target.href);
|
|
57
|
+
else window.history.pushState(null, "", target.href);
|
|
58
|
+
window.dispatchEvent(new Event("camox:navigation"));
|
|
59
|
+
};
|
|
60
|
+
$[1] = runtimeBasePath;
|
|
61
|
+
$[2] = t1;
|
|
62
|
+
} else t1 = $[2];
|
|
63
|
+
const navigate = t1;
|
|
64
|
+
let t2;
|
|
65
|
+
if ($[3] !== runtimeBasePath) {
|
|
66
|
+
t2 = () => getStudioLocation(runtimeBasePath);
|
|
67
|
+
$[3] = runtimeBasePath;
|
|
68
|
+
$[4] = t2;
|
|
69
|
+
} else t2 = $[4];
|
|
70
|
+
const getLocation = t2;
|
|
71
|
+
let t3;
|
|
72
|
+
if ($[5] !== href) {
|
|
73
|
+
t3 = new URL(href);
|
|
74
|
+
$[5] = href;
|
|
75
|
+
$[6] = t3;
|
|
76
|
+
} else t3 = $[6];
|
|
77
|
+
let t4;
|
|
78
|
+
if ($[7] !== href) {
|
|
79
|
+
t4 = new URL(href);
|
|
80
|
+
$[7] = href;
|
|
81
|
+
$[8] = t4;
|
|
82
|
+
} else t4 = $[8];
|
|
83
|
+
let t5;
|
|
84
|
+
if ($[9] !== href || $[10] !== pathname || $[11] !== t3.hash || $[12] !== t4.search) {
|
|
85
|
+
t5 = {
|
|
86
|
+
hash: t3.hash,
|
|
87
|
+
href,
|
|
88
|
+
pathname,
|
|
89
|
+
search: t4.search
|
|
90
|
+
};
|
|
91
|
+
$[9] = href;
|
|
92
|
+
$[10] = pathname;
|
|
93
|
+
$[11] = t3.hash;
|
|
94
|
+
$[12] = t4.search;
|
|
95
|
+
$[13] = t5;
|
|
96
|
+
} else t5 = $[13];
|
|
97
|
+
let t6;
|
|
98
|
+
if ($[14] !== children || $[15] !== getLocation || $[16] !== navigate || $[17] !== t5) {
|
|
99
|
+
t6 = /* @__PURE__ */ jsx(NavigationProvider, {
|
|
100
|
+
getLocation,
|
|
101
|
+
initialLocation: t5,
|
|
102
|
+
navigate,
|
|
103
|
+
children
|
|
104
|
+
});
|
|
105
|
+
$[14] = children;
|
|
106
|
+
$[15] = getLocation;
|
|
107
|
+
$[16] = navigate;
|
|
108
|
+
$[17] = t5;
|
|
109
|
+
$[18] = t6;
|
|
110
|
+
} else t6 = $[18];
|
|
111
|
+
return t6;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
//#endregion
|
|
115
|
+
export { StudioNavigationProvider };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CamoxApp } from "../../core/createApp.js";
|
|
2
|
+
import { StudioRenderInput } from "./studioApp.js";
|
|
3
|
+
|
|
4
|
+
//#region src/features/runtime/studioServer.d.ts
|
|
5
|
+
declare function renderStudioWithApp(input: StudioRenderInput & {
|
|
6
|
+
camoxApp: CamoxApp;
|
|
7
|
+
}): Promise<string>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { renderStudioWithApp };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { StudioApp } from "./studioApp.js";
|
|
2
|
+
import { QueryClient, hydrate } from "@tanstack/react-query";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { renderToString } from "react-dom/server";
|
|
5
|
+
|
|
6
|
+
//#region src/features/runtime/studioServer.tsx
|
|
7
|
+
async function renderStudioWithApp(input) {
|
|
8
|
+
const queryClient = new QueryClient();
|
|
9
|
+
hydrate(queryClient, input.dehydratedState);
|
|
10
|
+
return renderToString(/* @__PURE__ */ jsx(StudioApp, {
|
|
11
|
+
camoxApp: input.camoxApp,
|
|
12
|
+
input,
|
|
13
|
+
queryClient
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { renderStudioWithApp };
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
+
import { Navigate, useLocation } from "../navigation/navigation.js";
|
|
1
2
|
import { useAuthState, useSignInRedirect } from "../../lib/auth.js";
|
|
2
3
|
import { trackClientEvent } from "../../lib/telemetry-client.js";
|
|
3
4
|
import { STUDIO_BASE_PATH } from "./routes.js";
|
|
4
5
|
import { Navbar } from "./components/Navbar.js";
|
|
5
6
|
import { c } from "react/compiler-runtime";
|
|
6
|
-
import { Navigate, useLocation } from "@tanstack/react-router";
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
|
|
10
10
|
//#region src/features/studio/CamoxStudio.tsx
|
|
11
11
|
const CamoxStudio = (t0) => {
|
|
12
12
|
const $ = c(14);
|
|
13
|
-
if ($[0] !== "
|
|
13
|
+
if ($[0] !== "869273f9f42924824ee2b9e5a0066bb2be142208aab9426269ff2984ede38347") {
|
|
14
14
|
for (let $i = 0; $i < 14; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
15
|
-
$[0] = "
|
|
15
|
+
$[0] = "869273f9f42924824ee2b9e5a0066bb2be142208aab9426269ff2984ede38347";
|
|
16
16
|
}
|
|
17
17
|
const { children } = t0;
|
|
18
18
|
const { isAuthenticated, isLoading: isLoadingAuth } = useAuthState();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Link as Link$1, useLocation, useNavigate } from "../../navigation/navigation.js";
|
|
1
2
|
import { actionsStore } from "../../provider/actionsStore.js";
|
|
2
3
|
import { useProjectSlug } from "../../../lib/auth.js";
|
|
3
4
|
import { pageQueries, projectQueries } from "../../../lib/queries.js";
|
|
@@ -9,10 +10,9 @@ import { ProjectMenu } from "./ProjectMenu.js";
|
|
|
9
10
|
import { UserButton } from "./UserButton.js";
|
|
10
11
|
import { c } from "react/compiler-runtime";
|
|
11
12
|
import { useQuery } from "@tanstack/react-query";
|
|
12
|
-
import { Link, useLocation, useNavigate } from "@tanstack/react-router";
|
|
13
13
|
import * as React from "react";
|
|
14
|
-
import { Kbd } from "@camox/ui/kbd";
|
|
15
14
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
+
import { Kbd } from "@camox/ui/kbd";
|
|
16
16
|
import { Button } from "@camox/ui/button";
|
|
17
17
|
import { Database, Globe, SearchIcon } from "lucide-react";
|
|
18
18
|
|
|
@@ -36,9 +36,9 @@ const links = [{
|
|
|
36
36
|
}];
|
|
37
37
|
const Navbar = () => {
|
|
38
38
|
const $ = c(19);
|
|
39
|
-
if ($[0] !== "
|
|
39
|
+
if ($[0] !== "9b1adcbc6464388cc572701469e917a5652b82c7ccc4e66be74fb1820176f49e") {
|
|
40
40
|
for (let $i = 0; $i < 19; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
41
|
-
$[0] = "
|
|
41
|
+
$[0] = "9b1adcbc6464388cc572701469e917a5652b82c7ccc4e66be74fb1820176f49e";
|
|
42
42
|
}
|
|
43
43
|
const projectSlug = useProjectSlug();
|
|
44
44
|
let t0;
|
|
@@ -78,7 +78,7 @@ const Navbar = () => {
|
|
|
78
78
|
} else t4 = $[8];
|
|
79
79
|
let t5;
|
|
80
80
|
if ($[9] !== pages || $[10] !== pathname) {
|
|
81
|
-
t5 = links.map((link, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Link, {
|
|
81
|
+
t5 = links.map((link, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Link$1, {
|
|
82
82
|
to: link.to,
|
|
83
83
|
className: cn("flex gap-2 items-center rounded-md px-4 py-2 text-sm font-medium", "hover:bg-accent hover:text-accent-foreground outline-none transition-[color,box-shadow] focus-visible:ring-ring/50 focus-visible:ring-[3px] focus-visible:outline-1", pages?.some((page) => page.fullPath === pathname) && index === 0 ? "bg-accent hover:bg-accent text-accent-foreground" : "text-muted-foreground"),
|
|
84
84
|
activeProps: { className: "bg-accent hover:bg-accent text-accent-foreground!" },
|
|
@@ -146,9 +146,9 @@ const Navbar = () => {
|
|
|
146
146
|
};
|
|
147
147
|
function useNavbarActions() {
|
|
148
148
|
const $ = c(4);
|
|
149
|
-
if ($[0] !== "
|
|
149
|
+
if ($[0] !== "9b1adcbc6464388cc572701469e917a5652b82c7ccc4e66be74fb1820176f49e") {
|
|
150
150
|
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
151
|
-
$[0] = "
|
|
151
|
+
$[0] = "9b1adcbc6464388cc572701469e917a5652b82c7ccc4e66be74fb1820176f49e";
|
|
152
152
|
}
|
|
153
153
|
const navigate = useNavigate();
|
|
154
154
|
let t0;
|