camox 0.45.0 → 0.47.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/hooks/useArtifactHost.js +2 -2
- package/dist/features/canvas/CamoxCanvas.js +438 -771
- package/dist/features/canvas/CanvasPageFrame.js +1 -3
- package/dist/features/canvas/CanvasPreviewPageSlot.js +26 -6
- package/dist/features/canvas/canvasCamera.js +24 -9
- package/dist/features/canvas/canvasFrameDocument.js +4 -19
- package/dist/features/canvas/canvasItems.js +12 -102
- package/dist/features/canvas/canvasStore.js +3 -92
- package/dist/features/canvas/sidebar/CanvasNavigator.js +81 -183
- package/dist/features/canvas/sidebar/CanvasSidebar.js +22 -28
- package/dist/features/canvas/sidebar/CuratedPageInspector.js +2 -2
- package/dist/features/canvas/useCanvasCamera.js +16 -31
- package/dist/features/canvas/useCanvasFrame.js +5 -6
- package/dist/features/preview/CamoxPreview.js +137 -120
- package/dist/features/preview/components/{AddBlockDialog.js → AddBlockSheet.js} +35 -32
- package/dist/features/preview/components/BlockActionsPopover.js +6 -6
- package/dist/features/preview/components/BlockThumbnail.js +31 -33
- package/dist/features/preview/components/Overlays.js +1 -1
- package/dist/features/preview/components/PageTree.js +1 -1
- package/dist/features/preview/components/PreviewPanel.js +1 -1
- package/dist/features/preview/components/PreviewToolbar.js +74 -85
- package/dist/features/preview/previewStore.js +9 -9
- package/dist/features/provider/CamoxProvider.js +8 -16
- package/dist/features/provider/CoreCamoxProvider.js +10 -12
- package/dist/features/provider/signInShortcut.js +60 -0
- package/dist/features/routes/pageRuntime.js +8 -8
- package/dist/features/runtime/RuntimeChrome.js +1 -1
- package/dist/features/runtime/pageApp.js +11 -39
- package/dist/features/runtime/runtime.d.ts +2 -7
- package/dist/features/runtime/runtime.js +6 -19
- package/dist/features/studio/FollowAgentProvider.js +11 -22
- package/dist/features/studio/components/FaviconDialog.js +3 -3
- package/dist/features/studio/followAgent.js +5 -14
- package/dist/features/studio/routes.js +1 -23
- package/dist/lib/auth.js +36 -24
- package/dist/lib/studio-reads.js +0 -20
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +4 -4
- package/skills/camox-expand/SKILL.md +5 -4
- package/dist/features/canvas/CanvasBlockFrame.js +0 -353
- package/dist/features/canvas/CanvasBlockHeader.js +0 -55
- package/dist/features/canvas/CanvasShelfMarker.js +0 -255
- package/dist/features/canvas/sidebar/CatalogBlockInspector.js +0 -189
- package/dist/features/provider/LocalhostPreviewProvider.js +0 -158
|
@@ -4,8 +4,6 @@ import { useViewLocale } from "../../lib/view-locale-context.js";
|
|
|
4
4
|
import { useLocation, useNavigate } from "../navigation/navigation.js";
|
|
5
5
|
import { useCamoxApp } from "../provider/components/CamoxAppContext.js";
|
|
6
6
|
import { reads, useReadQueries, useReadQuery } from "../../lib/studio-reads.js";
|
|
7
|
-
import { useLocalizedPath } from "../../lib/view-locale.js";
|
|
8
|
-
import { blockCatalogPath } from "./routes.js";
|
|
9
7
|
import { FollowAgentContext } from "./followAgentContext.js";
|
|
10
8
|
import { canvasPageId, getCanvasPages } from "../canvas/canvasPages.js";
|
|
11
9
|
import { selectedCanvasPage } from "../canvas/canvasSelection.js";
|
|
@@ -103,12 +101,11 @@ function _temp(id) {
|
|
|
103
101
|
}
|
|
104
102
|
/** Where the editor is, and the Studio content following locates the agent's touches with. */
|
|
105
103
|
function useFollowWhere(runtimeBasePath) {
|
|
106
|
-
const $ = c(
|
|
104
|
+
const $ = c(35);
|
|
107
105
|
const app = useCamoxApp();
|
|
108
106
|
const projectUuid = useProjectUuid();
|
|
109
107
|
const location = useLocation();
|
|
110
108
|
const { locale, locales } = useViewLocale();
|
|
111
|
-
const localized = useLocalizedPath();
|
|
112
109
|
let t0;
|
|
113
110
|
if ($[0] !== projectUuid) {
|
|
114
111
|
t0 = reads.project({ projectUuid });
|
|
@@ -211,28 +208,20 @@ function useFollowWhere(runtimeBasePath) {
|
|
|
211
208
|
} else t9 = $[29];
|
|
212
209
|
const t10 = current?.key ?? null;
|
|
213
210
|
let t11;
|
|
214
|
-
if ($[30] !==
|
|
215
|
-
t11 =
|
|
216
|
-
$[30] = localized;
|
|
217
|
-
$[31] = t11;
|
|
218
|
-
} else t11 = $[31];
|
|
219
|
-
let t12;
|
|
220
|
-
if ($[32] !== locale.tag || $[33] !== pages || $[34] !== t10 || $[35] !== t11 || $[36] !== t9) {
|
|
221
|
-
t12 = {
|
|
211
|
+
if ($[30] !== locale.tag || $[31] !== pages || $[32] !== t10 || $[33] !== t9) {
|
|
212
|
+
t11 = {
|
|
222
213
|
pages,
|
|
223
214
|
locale: locale.tag,
|
|
224
215
|
location: t9,
|
|
225
|
-
pageKey: t10
|
|
226
|
-
blockCatalogPath: t11
|
|
216
|
+
pageKey: t10
|
|
227
217
|
};
|
|
228
|
-
$[
|
|
229
|
-
$[
|
|
230
|
-
$[
|
|
231
|
-
$[
|
|
232
|
-
$[
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
return t12;
|
|
218
|
+
$[30] = locale.tag;
|
|
219
|
+
$[31] = pages;
|
|
220
|
+
$[32] = t10;
|
|
221
|
+
$[33] = t9;
|
|
222
|
+
$[34] = t11;
|
|
223
|
+
} else t11 = $[34];
|
|
224
|
+
return t11;
|
|
236
225
|
}
|
|
237
226
|
function _temp2(page) {
|
|
238
227
|
return [page.id, page.layoutId];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getApiUrl } from "../../../lib/api-client.js";
|
|
2
2
|
import { reads, useStudioCache } from "../../../lib/studio-reads.js";
|
|
3
3
|
import { projectMutations } from "../../../lib/queries.js";
|
|
4
|
-
import {
|
|
4
|
+
import { buildDefaultFaviconUrl, buildFaviconUrl } from "../../routes/pageRuntime.js";
|
|
5
5
|
import { c } from "react/compiler-runtime";
|
|
6
6
|
import * as React from "react";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -63,7 +63,7 @@ function FaviconForm(t0) {
|
|
|
63
63
|
const [hasCurrent, setHasCurrent] = React.useState(false);
|
|
64
64
|
let t1;
|
|
65
65
|
if ($[0] !== project) {
|
|
66
|
-
t1 = buildFaviconUrl(getApiUrl(), project, {
|
|
66
|
+
t1 = buildFaviconUrl(getApiUrl(), project, { withDefault: false });
|
|
67
67
|
$[0] = project;
|
|
68
68
|
$[1] = t1;
|
|
69
69
|
} else t1 = $[1];
|
|
@@ -202,7 +202,7 @@ function FaviconForm(t0) {
|
|
|
202
202
|
const showsFavicon = pending ? pending.type === "upload" : hasCurrent;
|
|
203
203
|
let t14;
|
|
204
204
|
if ($[27] !== currentUrl || $[28] !== pendingUrl || $[29] !== showsFavicon) {
|
|
205
|
-
t14 = pendingUrl ?? (showsFavicon ? currentUrl :
|
|
205
|
+
t14 = pendingUrl ?? (showsFavicon ? currentUrl : buildDefaultFaviconUrl(getApiUrl()));
|
|
206
206
|
$[27] = currentUrl;
|
|
207
207
|
$[28] = pendingUrl;
|
|
208
208
|
$[29] = showsFavicon;
|
|
@@ -34,8 +34,7 @@ function locate(where, here, touch) {
|
|
|
34
34
|
return page ? at({ key: page.key }, touch.blockId) : null;
|
|
35
35
|
}
|
|
36
36
|
const placement = here?.blocks?.find((block) => block.type === touch.blockType);
|
|
37
|
-
|
|
38
|
-
return elsewhere ? null : { catalog: touch.blockType };
|
|
37
|
+
return here && placement ? at({ key: here.key }, placement.id) : null;
|
|
39
38
|
}
|
|
40
39
|
function destinationOf(where, batch) {
|
|
41
40
|
const here = currentPage(where);
|
|
@@ -50,7 +49,6 @@ function destinationOf(where, batch) {
|
|
|
50
49
|
return page ? `key:${page.key}` : refKey(ref);
|
|
51
50
|
};
|
|
52
51
|
for (const at of located) {
|
|
53
|
-
if ("catalog" in at) continue;
|
|
54
52
|
const key = identity(at.page);
|
|
55
53
|
const entry = touched.get(key) ?? {
|
|
56
54
|
page: at.page,
|
|
@@ -61,13 +59,7 @@ function destinationOf(where, batch) {
|
|
|
61
59
|
if (at.blockId && !entry.blockIds.includes(at.blockId)) entry.blockIds.push(at.blockId);
|
|
62
60
|
touched.set(key, entry);
|
|
63
61
|
}
|
|
64
|
-
if (touched.size === 0)
|
|
65
|
-
const catalog = located.find((at) => "catalog" in at);
|
|
66
|
-
return catalog && "catalog" in catalog ? {
|
|
67
|
-
kind: "catalog",
|
|
68
|
-
blockType: catalog.catalog
|
|
69
|
-
} : null;
|
|
70
|
-
}
|
|
62
|
+
if (touched.size === 0) return null;
|
|
71
63
|
const order = (ref) => {
|
|
72
64
|
const page = findPage(where, ref);
|
|
73
65
|
return page ? where.pages.indexOf(page) : where.pages.length;
|
|
@@ -75,7 +67,6 @@ function destinationOf(where, batch) {
|
|
|
75
67
|
const entries = [...touched.values()];
|
|
76
68
|
const chosen = (here && touched.get(`key:${here.key}`)) ?? entries.reduce((best, entry) => entry.count > best.count || entry.count === best.count && order(entry.page) < order(best.page) ? entry : best);
|
|
77
69
|
return {
|
|
78
|
-
kind: "page",
|
|
79
70
|
page: chosen.page,
|
|
80
71
|
blockIds: chosen.blockIds
|
|
81
72
|
};
|
|
@@ -169,11 +160,11 @@ function createFollowAgent({ navigate, where: initial }) {
|
|
|
169
160
|
return;
|
|
170
161
|
}
|
|
171
162
|
const destination = pendingNavigation;
|
|
172
|
-
const pathname =
|
|
163
|
+
const pathname = findPage(where, destination.page)?.pathname;
|
|
173
164
|
if (!pathname) return;
|
|
174
165
|
pendingNavigation = null;
|
|
175
166
|
arrivedAt = Date.now();
|
|
176
|
-
blocksToSelect = destination.
|
|
167
|
+
blocksToSelect = destination.blockIds.length ? destination : null;
|
|
177
168
|
selected = null;
|
|
178
169
|
navigate({
|
|
179
170
|
to: `${pathname}${where.location.search}`,
|
|
@@ -208,7 +199,7 @@ function createFollowAgent({ navigate, where: initial }) {
|
|
|
208
199
|
const destination = destinationOf(where, batch);
|
|
209
200
|
if (!destination) return;
|
|
210
201
|
const here = currentPage(where);
|
|
211
|
-
if (
|
|
202
|
+
if (here && findPage(where, destination.page) === here) {
|
|
212
203
|
pendingNavigation = null;
|
|
213
204
|
clearTimer();
|
|
214
205
|
if (!destination.blockIds.length) return;
|
|
@@ -27,28 +27,6 @@ function matchCollectionContentPath(pathname) {
|
|
|
27
27
|
}
|
|
28
28
|
/** The Studio URL of the Canvas with nothing selected. */
|
|
29
29
|
const STUDIO_CANVAS_PATH = `${STUDIO_BASE_PATH}/canvas`;
|
|
30
|
-
const STUDIO_BLOCKS_PATH = `${STUDIO_BASE_PATH}/blocks`;
|
|
31
|
-
/** The Studio URL of a block of the Block Catalog. */
|
|
32
|
-
const blockCatalogPath = (blockId) => `${STUDIO_BLOCKS_PATH}/${encodeURIComponent(blockId)}`;
|
|
33
|
-
/** The id of the Block Catalog block a pathname selects, if any. */
|
|
34
|
-
function matchBlockCatalogPath(pathname) {
|
|
35
|
-
const match = /^\/camox\/blocks\/([^/]+)$/.exec(pathname);
|
|
36
|
-
if (!match) return null;
|
|
37
|
-
try {
|
|
38
|
-
return decodeURIComponent(match[1]) || null;
|
|
39
|
-
} catch {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* A location that only exists on the Canvas: the Canvas with
|
|
45
|
-
* nothing selected, or a block of the Block Catalog.
|
|
46
|
-
*/
|
|
47
|
-
function matchCanvasOnlyPath(pathname) {
|
|
48
|
-
if (pathname === "/camox/canvas") return {};
|
|
49
|
-
const blockId = matchBlockCatalogPath(pathname);
|
|
50
|
-
return blockId ? { blockId } : null;
|
|
51
|
-
}
|
|
52
30
|
|
|
53
31
|
//#endregion
|
|
54
|
-
export { STUDIO_ASSETS_PATH, STUDIO_BASE_PATH,
|
|
32
|
+
export { STUDIO_ASSETS_PATH, STUDIO_BASE_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH, STUDIO_ROUTE_SEGMENT, collectionContentPath, matchCollectionContentPath };
|
package/dist/lib/auth.js
CHANGED
|
@@ -285,46 +285,58 @@ function useSessionState(authClient, track) {
|
|
|
285
285
|
return React.useSyncExternalStore(track ? subscribe : noSubscription, getSnapshot, getSnapshot);
|
|
286
286
|
}
|
|
287
287
|
function useAuthState() {
|
|
288
|
-
const $ = c(
|
|
289
|
-
const { authClient, initialAuthenticated: t0 } = useAuthContext();
|
|
288
|
+
const $ = c(9);
|
|
289
|
+
const { authClient, initialAuthenticated: t0, exchangingToken: t1 } = useAuthContext();
|
|
290
290
|
const initialAuthenticated = t0 === void 0 ? false : t0;
|
|
291
|
+
const exchangingToken = t1 === void 0 ? false : t1;
|
|
291
292
|
const hydrated = React.useSyncExternalStore(subscribeToHydration, _temp2, _temp3);
|
|
292
|
-
let
|
|
293
|
+
let t2;
|
|
293
294
|
if ($[0] !== hydrated || $[1] !== initialAuthenticated) {
|
|
294
|
-
|
|
295
|
+
t2 = initialAuthenticated || hydrated && hasStoredAuthCookie();
|
|
295
296
|
$[0] = hydrated;
|
|
296
297
|
$[1] = initialAuthenticated;
|
|
297
|
-
$[2] =
|
|
298
|
-
} else
|
|
299
|
-
const tracksSession =
|
|
298
|
+
$[2] = t2;
|
|
299
|
+
} else t2 = $[2];
|
|
300
|
+
const tracksSession = t2;
|
|
300
301
|
const { data: session, isPending } = useSessionState(authClient, tracksSession);
|
|
301
|
-
if (!
|
|
302
|
-
const t2 = !hydrated;
|
|
302
|
+
if (exchangingToken && !initialAuthenticated) {
|
|
303
303
|
let t3;
|
|
304
|
-
if ($[3]
|
|
304
|
+
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
|
305
305
|
t3 = {
|
|
306
306
|
isAuthenticated: false,
|
|
307
|
-
isLoading:
|
|
307
|
+
isLoading: true
|
|
308
308
|
};
|
|
309
|
-
$[3] =
|
|
310
|
-
|
|
311
|
-
} else t3 = $[4];
|
|
309
|
+
$[3] = t3;
|
|
310
|
+
} else t3 = $[3];
|
|
312
311
|
return t3;
|
|
313
312
|
}
|
|
313
|
+
if (!tracksSession) {
|
|
314
|
+
const t3 = !hydrated;
|
|
315
|
+
let t4;
|
|
316
|
+
if ($[4] !== t3) {
|
|
317
|
+
t4 = {
|
|
318
|
+
isAuthenticated: false,
|
|
319
|
+
isLoading: t3
|
|
320
|
+
};
|
|
321
|
+
$[4] = t3;
|
|
322
|
+
$[5] = t4;
|
|
323
|
+
} else t4 = $[5];
|
|
324
|
+
return t4;
|
|
325
|
+
}
|
|
314
326
|
const useInitial = !hydrated || isPending;
|
|
315
|
-
const
|
|
316
|
-
const
|
|
317
|
-
let
|
|
318
|
-
if ($[
|
|
319
|
-
|
|
320
|
-
isAuthenticated:
|
|
321
|
-
isLoading:
|
|
327
|
+
const t3 = useInitial ? initialAuthenticated : !!session;
|
|
328
|
+
const t4 = useInitial && !initialAuthenticated;
|
|
329
|
+
let t5;
|
|
330
|
+
if ($[6] !== t3 || $[7] !== t4) {
|
|
331
|
+
t5 = {
|
|
332
|
+
isAuthenticated: t3,
|
|
333
|
+
isLoading: t4
|
|
322
334
|
};
|
|
323
|
-
$[5] = t2;
|
|
324
335
|
$[6] = t3;
|
|
325
336
|
$[7] = t4;
|
|
326
|
-
|
|
327
|
-
|
|
337
|
+
$[8] = t5;
|
|
338
|
+
} else t5 = $[8];
|
|
339
|
+
return t5;
|
|
328
340
|
}
|
|
329
341
|
function _temp3() {
|
|
330
342
|
return false;
|
package/dist/lib/studio-reads.js
CHANGED
|
@@ -148,26 +148,6 @@ const reads = {
|
|
|
148
148
|
fetch: async ({ api, signal }, { projectId }) => Object.fromEntries((await api.blocks.getUsageCounts({ projectId }, { signal })).map(({ type, count }) => [type, count])),
|
|
149
149
|
staleTime: Infinity
|
|
150
150
|
}),
|
|
151
|
-
pagesUsingBlock: entry({
|
|
152
|
-
key: ({ type }) => [
|
|
153
|
-
...usageCountsPrefix,
|
|
154
|
-
"pages",
|
|
155
|
-
type
|
|
156
|
-
],
|
|
157
|
-
fetch: ({ api, signal }, { projectId, type }) => api.blocks.getPagesUsing({
|
|
158
|
-
projectId,
|
|
159
|
-
type
|
|
160
|
-
}, { signal }),
|
|
161
|
-
staleTime: Infinity
|
|
162
|
-
}),
|
|
163
|
-
syncedContent: entry({
|
|
164
|
-
key: ({ type }) => queryKeys.blocks.getSyncedContent(type),
|
|
165
|
-
fetch: ({ api, signal }, { projectId, type }) => api.blocks.getSyncedContent({
|
|
166
|
-
projectId,
|
|
167
|
-
type
|
|
168
|
-
}, { signal }),
|
|
169
|
-
staleTime: Infinity
|
|
170
|
-
}),
|
|
171
151
|
pageMarkdown: entry({
|
|
172
152
|
key: (pageId) => queryKeys.blocks.getPageMarkdown(pageId),
|
|
173
153
|
fetch: async ({ api, signal }, pageId) => (await api.blocks.getPageMarkdown({ pageId }, { signal })).markdown,
|
package/dist/package.js
CHANGED