camox 0.45.0 → 0.46.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.
Files changed (39) hide show
  1. package/dist/core/hooks/useArtifactHost.js +2 -2
  2. package/dist/features/canvas/CamoxCanvas.js +438 -771
  3. package/dist/features/canvas/CanvasPageFrame.js +1 -3
  4. package/dist/features/canvas/CanvasPreviewPageSlot.js +26 -6
  5. package/dist/features/canvas/canvasCamera.js +3 -3
  6. package/dist/features/canvas/canvasFrameDocument.js +4 -19
  7. package/dist/features/canvas/canvasItems.js +12 -102
  8. package/dist/features/canvas/canvasStore.js +3 -92
  9. package/dist/features/canvas/sidebar/CanvasNavigator.js +81 -183
  10. package/dist/features/canvas/sidebar/CanvasSidebar.js +22 -28
  11. package/dist/features/canvas/sidebar/CuratedPageInspector.js +2 -2
  12. package/dist/features/canvas/useCanvasCamera.js +0 -20
  13. package/dist/features/canvas/useCanvasFrame.js +5 -6
  14. package/dist/features/preview/CamoxPreview.js +3 -3
  15. package/dist/features/preview/components/{AddBlockDialog.js → AddBlockSheet.js} +35 -32
  16. package/dist/features/preview/components/BlockActionsPopover.js +6 -6
  17. package/dist/features/preview/components/BlockThumbnail.js +31 -33
  18. package/dist/features/preview/components/Overlays.js +1 -1
  19. package/dist/features/preview/components/PageTree.js +1 -1
  20. package/dist/features/preview/components/PreviewPanel.js +1 -1
  21. package/dist/features/preview/previewStore.js +9 -9
  22. package/dist/features/provider/CoreCamoxProvider.js +9 -6
  23. package/dist/features/routes/pageRuntime.js +8 -8
  24. package/dist/features/runtime/runtime.d.ts +2 -7
  25. package/dist/features/runtime/runtime.js +6 -19
  26. package/dist/features/studio/FollowAgentProvider.js +11 -22
  27. package/dist/features/studio/components/FaviconDialog.js +3 -3
  28. package/dist/features/studio/followAgent.js +5 -14
  29. package/dist/features/studio/routes.js +1 -23
  30. package/dist/lib/auth.js +36 -24
  31. package/dist/lib/studio-reads.js +0 -20
  32. package/dist/package.js +1 -1
  33. package/dist/studio.css +1 -1
  34. package/package.json +4 -4
  35. package/skills/camox-expand/SKILL.md +5 -4
  36. package/dist/features/canvas/CanvasBlockFrame.js +0 -353
  37. package/dist/features/canvas/CanvasBlockHeader.js +0 -55
  38. package/dist/features/canvas/CanvasShelfMarker.js +0 -255
  39. package/dist/features/canvas/sidebar/CatalogBlockInspector.js +0 -189
@@ -50,13 +50,13 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
50
50
  const blockIndex = pageBlocks.findIndex((b) => b.id === block.id);
51
51
  const afterPosition = blockIndex > 0 ? pageBlocks[blockIndex - 1].position : "";
52
52
  previewStore.send({
53
- type: "openAddBlockDialog",
53
+ type: "openAddBlockSheet",
54
54
  afterPosition
55
55
  });
56
56
  };
57
57
  const handleAddBlockBelow = (block) => {
58
58
  previewStore.send({
59
- type: "openAddBlockDialog",
59
+ type: "openAddBlockSheet",
60
60
  afterPosition: block.position
61
61
  });
62
62
  };
@@ -104,7 +104,7 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
104
104
  isLayoutBlock && layoutSlot === "before" && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(CommandGroup, { children: /* @__PURE__ */ jsx(CommandItem, {
105
105
  onSelect: () => {
106
106
  previewStore.send({
107
- type: "openAddBlockDialog",
107
+ type: "openAddBlockSheet",
108
108
  afterPosition: ""
109
109
  });
110
110
  onOpenChange(false);
@@ -118,7 +118,7 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
118
118
  onSelect: () => {
119
119
  const lastPageBlock = pageBlocks[pageBlocks.length - 1];
120
120
  previewStore.send({
121
- type: "openAddBlockDialog",
121
+ type: "openAddBlockSheet",
122
122
  afterPosition: lastPageBlock?.position
123
123
  });
124
124
  onOpenChange(false);
@@ -419,7 +419,7 @@ function useBlockActionsShortcuts() {
419
419
  const block_2 = pageBlocks.find((b_6) => b_6.id === sel_7.blockId);
420
420
  if (!block_2) return;
421
421
  previewStore.send({
422
- type: "openAddBlockDialog",
422
+ type: "openAddBlockSheet",
423
423
  afterPosition: block_2.position
424
424
  });
425
425
  }
@@ -444,7 +444,7 @@ function useBlockActionsShortcuts() {
444
444
  if (blockIndex === -1) return;
445
445
  const afterPosition_1 = blockIndex > 0 ? pageBlocks[blockIndex - 1].position : "";
446
446
  previewStore.send({
447
- type: "openAddBlockDialog",
447
+ type: "openAddBlockSheet",
448
448
  afterPosition: afterPosition_1
449
449
  });
450
450
  }
@@ -27,6 +27,7 @@ const ThumbnailFrame = (t0) => {
27
27
  $[1] = t1;
28
28
  } else t1 = $[1];
29
29
  const bundle = t1;
30
+ const initialization = React.useRef(0);
30
31
  let t2;
31
32
  if ($[2] !== frame?.contentDocument || $[3] !== sourceDocument) {
32
33
  t2 = () => {
@@ -38,8 +39,15 @@ const ThumbnailFrame = (t0) => {
38
39
  const base = doc.createElement("base");
39
40
  base.href = source.baseURI;
40
41
  doc.head.appendChild(base);
42
+ const stylesheetsLoaded = [];
41
43
  source.querySelectorAll("style, link[rel=\"stylesheet\"]").forEach((style) => {
42
- if (isSiteStyle(style)) doc.head.appendChild(style.cloneNode(true));
44
+ if (!isSiteStyle(style)) return;
45
+ const clone = style.cloneNode(true);
46
+ if (clone.localName === "link") stylesheetsLoaded.push(new Promise((resolve) => {
47
+ clone.addEventListener("load", resolve, { once: true });
48
+ clone.addEventListener("error", resolve, { once: true });
49
+ }));
50
+ doc.head.appendChild(clone);
43
51
  });
44
52
  if (source !== document) for (const [from, to] of [
45
53
  [source.documentElement, doc.documentElement],
@@ -53,7 +61,10 @@ const ThumbnailFrame = (t0) => {
53
61
  reset.textContent = "\n html, body { margin: 0 !important; overflow: hidden !important; }\n *, *::before, *::after {\n animation: none !important;\n transition: none !important;\n caret-color: transparent !important;\n }\n ";
54
62
  doc.head.appendChild(reset);
55
63
  doc.body.setAttribute("inert", "");
56
- setRoot(mount);
64
+ const generation = initialization.current = initialization.current + 1;
65
+ Promise.all(stylesheetsLoaded).then(() => {
66
+ if (initialization.current === generation) setRoot(mount);
67
+ });
57
68
  };
58
69
  $[2] = frame?.contentDocument;
59
70
  $[3] = sourceDocument;
@@ -185,12 +196,11 @@ const ThumbnailFrame = (t0) => {
185
196
  return t14;
186
197
  };
187
198
  const BlockThumbnail = (t0) => {
188
- const $ = c(15);
199
+ const $ = c(11);
189
200
  const { block, className } = t0;
190
201
  const ref = React.useRef(null);
191
202
  const [isVisible, setIsVisible] = React.useState(false);
192
203
  const [width, setWidth] = React.useState(0);
193
- const checkerSize = 8 * (1 + width / VIEWPORT_WIDTH);
194
204
  let t1;
195
205
  let t2;
196
206
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
@@ -222,46 +232,34 @@ const BlockThumbnail = (t0) => {
222
232
  React.useEffect(t1, t2);
223
233
  let t3;
224
234
  if ($[2] !== className) {
225
- t3 = cn("checkered pointer-events-none relative flex h-28 w-full items-center overflow-hidden", className);
235
+ t3 = cn("bg-muted pointer-events-none relative flex h-28 w-full items-center overflow-hidden", className);
226
236
  $[2] = className;
227
237
  $[3] = t3;
228
238
  } else t3 = $[3];
229
239
  let t4;
230
- if ($[4] !== checkerSize || $[5] !== width) {
231
- t4 = width > 0 ? {
232
- backgroundSize: `${checkerSize * 2}px ${checkerSize * 2}px`,
233
- backgroundPosition: `0 0, 0 ${checkerSize}px, ${checkerSize}px ${-checkerSize}px, ${-checkerSize}px 0`
234
- } : void 0;
235
- $[4] = checkerSize;
236
- $[5] = width;
237
- $[6] = t4;
238
- } else t4 = $[6];
239
- let t5;
240
- if ($[7] !== block || $[8] !== isVisible || $[9] !== width) {
241
- t5 = isVisible && width > 0 && /* @__PURE__ */ jsx(ThumbnailFrame, {
240
+ if ($[4] !== block || $[5] !== isVisible || $[6] !== width) {
241
+ t4 = isVisible && width > 0 && /* @__PURE__ */ jsx(ThumbnailFrame, {
242
242
  block,
243
243
  width
244
244
  });
245
- $[7] = block;
246
- $[8] = isVisible;
247
- $[9] = width;
248
- $[10] = t5;
249
- } else t5 = $[10];
250
- let t6;
251
- if ($[11] !== t3 || $[12] !== t4 || $[13] !== t5) {
252
- t6 = /* @__PURE__ */ jsx("div", {
245
+ $[4] = block;
246
+ $[5] = isVisible;
247
+ $[6] = width;
248
+ $[7] = t4;
249
+ } else t4 = $[7];
250
+ let t5;
251
+ if ($[8] !== t3 || $[9] !== t4) {
252
+ t5 = /* @__PURE__ */ jsx("div", {
253
253
  ref,
254
254
  className: t3,
255
- style: t4,
256
255
  "aria-hidden": "true",
257
- children: t5
256
+ children: t4
258
257
  });
259
- $[11] = t3;
260
- $[12] = t4;
261
- $[13] = t5;
262
- $[14] = t6;
263
- } else t6 = $[14];
264
- return t6;
258
+ $[8] = t3;
259
+ $[9] = t4;
260
+ $[10] = t5;
261
+ } else t5 = $[10];
262
+ return t5;
265
263
  };
266
264
 
267
265
  //#endregion
@@ -39,7 +39,7 @@ function CuratedAddBlockListener(t0) {
39
39
  else if (blockIndex === 0) afterPosition = "";
40
40
  }
41
41
  previewStore.send({
42
- type: "openAddBlockDialog",
42
+ type: "openAddBlockSheet",
43
43
  afterPosition
44
44
  });
45
45
  }
@@ -835,7 +835,7 @@ function _temp3(block_3) {
835
835
  return /* @__PURE__ */ jsx(SortableBlock, { block: block_3 }, block_3.id);
836
836
  }
837
837
  function _temp4() {
838
- previewStore.send({ type: "openAddBlockDialog" });
838
+ previewStore.send({ type: "openAddBlockSheet" });
839
839
  }
840
840
 
841
841
  //#endregion
@@ -478,7 +478,7 @@ const PreviewPanel = (t0) => {
478
478
  $[43] = t19;
479
479
  } else t19 = $[43];
480
480
  const t20 = !placed && "inset-0";
481
- const t21 = underCanvas && (!placed || placed.hidden) && "invisible";
481
+ const t21 = underCanvas && !placed && "invisible";
482
482
  const t22 = device && "checkered flex items-center justify-center";
483
483
  let t23;
484
484
  if ($[44] !== t20 || $[45] !== t21 || $[46] !== t22) {
@@ -97,7 +97,7 @@ const selectIsCanvasShown = (state) => state.context.view === "canvas";
97
97
  const initialPreviewContext = {
98
98
  view: "preview",
99
99
  isToolbarHidden: false,
100
- addBlockDialog: null,
100
+ addBlockSheet: null,
101
101
  isCreatePageModalOpen: false,
102
102
  editingPageId: null,
103
103
  viewportMode: "full",
@@ -150,7 +150,7 @@ const previewStore = createStore({
150
150
  return {
151
151
  ...context,
152
152
  editingContext: owner ? targetContext(owner, null) : null,
153
- addBlockDialog: null
153
+ addBlockSheet: null
154
154
  };
155
155
  },
156
156
  activateLayout: (context, event) => {
@@ -162,7 +162,7 @@ const previewStore = createStore({
162
162
  return {
163
163
  ...context,
164
164
  editingContext: targetContext(owner, null),
165
- addBlockDialog: null
165
+ addBlockSheet: null
166
166
  };
167
167
  },
168
168
  selectTarget: (context, event) => ({
@@ -175,7 +175,7 @@ const previewStore = createStore({
175
175
  type: "block",
176
176
  blockId: event.blockId
177
177
  }),
178
- addBlockDialog: null
178
+ addBlockSheet: null
179
179
  }),
180
180
  selectItem: (context, event) => ({
181
181
  ...context,
@@ -312,13 +312,13 @@ const previewStore = createStore({
312
312
  selection: null
313
313
  } : null
314
314
  }),
315
- openAddBlockDialog: (context, event) => ({
315
+ openAddBlockSheet: (context, event) => ({
316
316
  ...context,
317
- addBlockDialog: { afterPosition: event.afterPosition }
317
+ addBlockSheet: { afterPosition: event.afterPosition }
318
318
  }),
319
- closeAddBlockDialog: (context) => ({
319
+ closeAddBlockSheet: (context) => ({
320
320
  ...context,
321
- addBlockDialog: null
321
+ addBlockSheet: null
322
322
  }),
323
323
  focusCreatedBlock: (context, event) => ({
324
324
  ...context,
@@ -326,7 +326,7 @@ const previewStore = createStore({
326
326
  type: "block",
327
327
  blockId: event.blockId
328
328
  }),
329
- addBlockDialog: null
329
+ addBlockSheet: null
330
330
  }),
331
331
  openCreatePageModal: (context) => ({
332
332
  ...context,
@@ -42,23 +42,26 @@ function CoreCamoxProvider({ apiUrl, authenticationUrl, camoxApp, children, proj
42
42
  if (!cached || replaceEqualDeep(cached, initialProject) !== cached) studioCache.set(read, initialProject);
43
43
  seededProject.current = initialProject;
44
44
  }
45
+ const { ready, error } = useProcessOtt(authClient, {
46
+ projectUuid,
47
+ apiUrl
48
+ }, initialAuthenticated);
49
+ const exchangingToken = !ready;
45
50
  const authContext = React.useMemo(() => ({
46
51
  authClient,
47
52
  authenticationUrl,
48
53
  apiUrl,
49
54
  projectUuid,
50
- initialAuthenticated
55
+ initialAuthenticated,
56
+ exchangingToken
51
57
  }), [
52
58
  authClient,
53
59
  authenticationUrl,
54
60
  apiUrl,
55
61
  projectUuid,
56
- initialAuthenticated
62
+ initialAuthenticated,
63
+ exchangingToken
57
64
  ]);
58
- const { ready, error } = useProcessOtt(authClient, {
59
- projectUuid,
60
- apiUrl
61
- }, initialAuthenticated);
62
65
  const [isPreviewHandoff, setIsPreviewHandoff] = React.useState(false);
63
66
  React.useEffect(() => {
64
67
  setIsPreviewHandoff(new URL(window.location.href).searchParams.has("camox-preview"));
@@ -174,16 +174,16 @@ async function resolveMemberProject({ apiUrl, authCookieHeader, projectUuid }) {
174
174
  }
175
175
  }
176
176
  /**
177
- * The project's favicon, which falls back to the Camox mark when none was uploaded. Pass
178
- * `placeholder: false` to get a 404 instead, to learn whether there is one.
177
+ * The project's favicon, which falls back to the default favicon when none was uploaded.
178
+ * Pass `withDefault: false` to get a 404 instead, to learn whether there is one.
179
179
  */
180
- function buildFaviconUrl(apiUrl, project, { placeholder = true } = {}) {
180
+ function buildFaviconUrl(apiUrl, project, { withDefault = true } = {}) {
181
181
  const url = `${apiUrl}/favicons/${project.id}?v=${project.updatedAt}`;
182
- return placeholder ? `${url}&placeholder=camox` : url;
182
+ return withDefault ? `${url}&default=camox` : url;
183
183
  }
184
- /** The Camox mark a project without a favicon shows. */
185
- function buildFaviconPlaceholderUrl(apiUrl) {
186
- return `${apiUrl}/favicons/placeholder`;
184
+ /** The default favicon, shown by a project without its own. */
185
+ function buildDefaultFaviconUrl(apiUrl) {
186
+ return `${apiUrl}/favicons/default`;
187
187
  }
188
188
  function buildCamoxPageLoaderData(apiUrl, page, origin) {
189
189
  return {
@@ -340,4 +340,4 @@ function buildCamoxPageHead(camoxApp, loaderData, locale) {
340
340
  }
341
341
 
342
342
  //#endregion
343
- export { buildCamoxPageHead, buildCamoxPageLoaderData, buildFaviconPlaceholderUrl, buildFaviconUrl, buildPageHead, buildPageMeta, createMarkdownResponse, createServerApiClient, createServerStudioCache, getMarkdownPath, isAuthSessionError, isNotFoundError, loadCamoxPage, loadCamoxPageForRequest, parseMarkdownPath, parseQuality, prefersMarkdown, readDraftOrLive, readScopeLocales, renderedHref, resolveMemberProject, withFrontMatter };
343
+ export { buildCamoxPageHead, buildCamoxPageLoaderData, buildDefaultFaviconUrl, buildFaviconUrl, buildPageHead, buildPageMeta, createMarkdownResponse, createServerApiClient, createServerStudioCache, getMarkdownPath, isAuthSessionError, isNotFoundError, loadCamoxPage, loadCamoxPageForRequest, parseMarkdownPath, parseQuality, prefersMarkdown, readDraftOrLive, readScopeLocales, renderedHref, resolveMemberProject, withFrontMatter };
@@ -33,13 +33,8 @@ export interface PageRenderInput extends DraftRead {
33
33
  previewHandoff?: boolean;
34
34
  previewDocument?: string;
35
35
  routeKind?: "studio" | "studio-content" | "studio-nested";
36
- /**
37
- * A location only the Canvas shows, instead of a Page: the Canvas
38
- * with nothing selected, or with a block of the Block Catalog selected.
39
- */
40
- canvasOnly?: {
41
- blockId?: string;
42
- };
36
+ /** Whether the location is the Canvas with nothing selected, which only the Canvas shows. */
37
+ canvasOnly?: boolean;
43
38
  project?: MemberProject;
44
39
  presentation?: "public" | "studio";
45
40
  derived?: {
@@ -7,7 +7,7 @@ import { RUNTIME_ROUTE_PATHS, matchRuntimeOwnedRoute } from "./runtimeRoutes.js"
7
7
  import { reads } from "../../lib/studio-reads.js";
8
8
  import { asCollectionItem, recordMarkdownTemplate, recordPlainText } from "../../core/recordItem.js";
9
9
  import { PLATFORM_SCRIPT } from "../../lib/platform.js";
10
- import { STUDIO_ASSETS_PATH, STUDIO_CONTENT_PATH, matchCanvasOnlyPath, matchCollectionContentPath } from "../studio/routes.js";
10
+ import { STUDIO_ASSETS_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH, matchCollectionContentPath } from "../studio/routes.js";
11
11
  import { STUDIO_THEME_SCRIPT } from "../studio/studioTheme.js";
12
12
  import { discoverLayoutPages, matchDerivedLayout } from "../../core/derivedRoutes.js";
13
13
  import { buildCamoxPageHead, buildFaviconUrl, buildPageHead, buildPageMeta, createMarkdownResponse, createServerApiClient, createServerStudioCache, isNotFoundError, loadCamoxPageForRequest, parseMarkdownPath, prefersMarkdown, readDraftOrLive, readScopeLocales, renderedHref, resolveMemberProject, withFrontMatter } from "../routes/pageRuntime.js";
@@ -76,7 +76,7 @@ function matchRuntimeRoute(pathname) {
76
76
  kind: "studio",
77
77
  pathname
78
78
  };
79
- if (matchCanvasOnlyPath(pathname)) return {
79
+ if (pathname === "/camox/canvas") return {
80
80
  kind: "canvas",
81
81
  pathname
82
82
  };
@@ -872,22 +872,10 @@ ${renderClientEntryScript(options.studioClientEntryUrl)}
872
872
  } });
873
873
  }
874
874
  /**
875
- * The Canvas with nothing selected, or a block of the Block Catalog, renders the
876
- * page app, like a Page, so selecting it keeps the Canvas mounted. A block path
877
- * without a page-content block of that id redirects home.
875
+ * The Canvas with nothing selected renders the page app, like a Page, so
876
+ * selecting it keeps the Canvas mounted.
878
877
  */
879
878
  async function createCanvasOnlyResponse({ options, pathname, located, request, dataOnly = false }) {
880
- const { blockId } = matchCanvasOnlyPath(located.path);
881
- const app = blockId ? await options.getCamoxApp?.() : void 0;
882
- const block = blockId ? app?.getBlockById(blockId) : void 0;
883
- if (blockId && (!block || block._internal.layoutOnly)) {
884
- if (dataOnly) return Response.json({
885
- kind: "canvas",
886
- message: "No block of the Block Catalog on this path",
887
- pathname
888
- }, { status: 404 });
889
- return Response.redirect(new URL(withRuntimeBasePath(localizedPath("/", located.locale), options.runtimeBasePath), request.url), 302);
890
- }
891
879
  if (!options.apiUrl || !options.authenticationUrl || !options.projectUuid || !dataOnly && !options.renderPage) return Response.json({
892
880
  message: "Camox page renderer is not configured.",
893
881
  kind: "canvas",
@@ -895,7 +883,7 @@ async function createCanvasOnlyResponse({ options, pathname, located, request, d
895
883
  }, { status: 500 });
896
884
  const { project, clearAuthCookie } = await resolveRequestMember(request, options);
897
885
  const studio = project !== void 0;
898
- const title = block?._internal.title ?? "Canvas";
886
+ const title = "Canvas";
899
887
  const input = {
900
888
  project,
901
889
  presentation: studio ? "studio" : "public",
@@ -911,10 +899,9 @@ async function createCanvasOnlyResponse({ options, pathname, located, request, d
911
899
  layoutIdentity: null,
912
900
  loaderData: null,
913
901
  dehydratedState: dehydrate(new QueryClient()),
914
- canvasOnly: blockId ? { blockId } : {},
902
+ canvasOnly: true,
915
903
  draftId: studio ? getRequestDraftId(request, options) : void 0
916
904
  };
917
- await preparePreviewDocument(input, options, await options.getDocument?.() ?? {}, "");
918
905
  const headers = {
919
906
  "Cache-Control": "private, no-store",
920
907
  Vary: "Cookie",
@@ -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(38);
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] !== localized) {
215
- t11 = (type) => localized(blockCatalogPath(type));
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
- $[32] = locale.tag;
229
- $[33] = pages;
230
- $[34] = t10;
231
- $[35] = t11;
232
- $[36] = t9;
233
- $[37] = t12;
234
- } else t12 = $[37];
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 { buildFaviconPlaceholderUrl, buildFaviconUrl } from "../../routes/pageRuntime.js";
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, { placeholder: false });
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 : buildFaviconPlaceholderUrl(getApiUrl()));
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
- if (here && placement) return at({ key: here.key }, placement.id);
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 = destination.kind === "catalog" ? where.blockCatalogPath(destination.blockType) : findPage(where, destination.page)?.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.kind === "page" && destination.blockIds.length ? destination : null;
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 (destination.kind === "page" && here && findPage(where, destination.page) === here) {
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, STUDIO_BLOCKS_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH, STUDIO_ROUTE_SEGMENT, blockCatalogPath, collectionContentPath, matchBlockCatalogPath, matchCanvasOnlyPath, matchCollectionContentPath };
32
+ export { STUDIO_ASSETS_PATH, STUDIO_BASE_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH, STUDIO_ROUTE_SEGMENT, collectionContentPath, matchCollectionContentPath };