camox 0.63.0 → 0.66.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 (60) hide show
  1. package/dist/core/createApp.d.ts +28 -28
  2. package/dist/core/createLayout.d.ts +1 -1
  3. package/dist/core/derivedRoutes.js +3 -30
  4. package/dist/core/editing/createEditableBlock.d.ts +604 -604
  5. package/dist/features/canvas/CamoxCanvas.js +195 -173
  6. package/dist/features/canvas/canvasCamera.js +11 -2
  7. package/dist/features/canvas/canvasFrameCapture.js +5 -12
  8. package/dist/features/canvas/canvasFrameDocument.js +90 -29
  9. package/dist/features/canvas/canvasItems.js +22 -6
  10. package/dist/features/canvas/sidebar/ContentSidebar.js +19 -21
  11. package/dist/features/canvas/sidebar/LayoutPageOverview.js +22 -49
  12. package/dist/features/canvas/sidebar/LayoutPageSeo.js +73 -76
  13. package/dist/features/canvas/sidebar/PageInspector.js +61 -50
  14. package/dist/features/canvas/sidebar/PageInspectorSkeleton.js +4 -4
  15. package/dist/features/canvas/useCanvasCamera.js +36 -15
  16. package/dist/features/page/CuratedPageContent.js +2 -1
  17. package/dist/features/page/UnplacedBlockContent.js +52 -0
  18. package/dist/features/preview/components/PageInfo.js +103 -100
  19. package/dist/features/preview/components/PreviewPanel.js +40 -12
  20. package/dist/features/preview/components/SidebarStack.js +78 -9
  21. package/dist/features/preview/strayCaretGuard.js +34 -0
  22. package/dist/features/provider/CoreCamoxProvider.js +5 -3
  23. package/dist/features/routes/pageRuntime.d.ts +2 -0
  24. package/dist/features/routes/pageRuntime.js +8 -5
  25. package/dist/features/runtime/RuntimeChrome.js +66 -40
  26. package/dist/features/runtime/pageApp.js +111 -74
  27. package/dist/features/runtime/pageClient.js +22 -2
  28. package/dist/features/runtime/runtime.d.ts +10 -0
  29. package/dist/features/runtime/runtime.js +314 -4
  30. package/dist/features/runtime/runtimeRoutes.d.ts +5 -0
  31. package/dist/features/runtime/runtimeRoutes.js +5 -0
  32. package/dist/features/studio/components/AgentSidebar.js +3 -3
  33. package/dist/features/studio/components/ChatWidget.js +106 -75
  34. package/dist/features/studio/components/ConnectAgent.js +313 -0
  35. package/dist/features/studio/components/DraftsControl.js +172 -159
  36. package/dist/features/studio/components/Patrol.js +605 -350
  37. package/dist/features/studio/components/ReviewDraftSheet.js +566 -430
  38. package/dist/features/studio/components/Squareling.js +74 -41
  39. package/dist/features/studio/components/ThreadComposer.js +192 -107
  40. package/dist/features/studio/components/ThreadMessages.js +95 -18
  41. package/dist/features/studio/components/UnnamedDraftBar.js +349 -0
  42. package/dist/features/studio/components/clientLogoPaths.js +10 -0
  43. package/dist/features/studio/findingSentence.js +37 -0
  44. package/dist/features/studio/patrollerBio.js +40 -0
  45. package/dist/features/studio/reportSentence.js +15 -0
  46. package/dist/features/studio/studioStore.js +36 -1
  47. package/dist/features/studio/workingSentence.js +10 -7
  48. package/dist/lib/api-client.d.ts +1 -0
  49. package/dist/lib/auth.js +34 -32
  50. package/dist/lib/queries.js +9 -1
  51. package/dist/lib/revisions.js +25 -3
  52. package/dist/lib/server-auth-cookie.js +17 -4
  53. package/dist/lib/studio-reads.d.ts +1 -1
  54. package/dist/lib/studio-reads.js +5 -1
  55. package/dist/lib/use-thread.js +1 -1
  56. package/dist/package.js +1 -1
  57. package/dist/studio.css +1 -1
  58. package/package.json +15 -4
  59. package/dist/features/canvas/sidebar/DerivedPageInspector.js +0 -49
  60. package/dist/features/canvas/sidebar/SingletonPageInspector.js +0 -39
@@ -5,8 +5,7 @@ import { CanvasInspectorBody, CanvasInspectorTitle } from "./CanvasInspector.js"
5
5
  import { PageInspectorSkeleton } from "./PageInspectorSkeleton.js";
6
6
  import { PreviewEditingOwnerContext } from "../../preview/previewSelection.js";
7
7
  import { CuratedPageInspector } from "./CuratedPageInspector.js";
8
- import { DerivedPageInspector } from "./DerivedPageInspector.js";
9
- import { SingletonPageInspector } from "./SingletonPageInspector.js";
8
+ import { LayoutPageOverview } from "./LayoutPageOverview.js";
10
9
  import { c } from "react/compiler-runtime";
11
10
  import * as React from "react";
12
11
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -38,8 +37,8 @@ var PageInspectorBoundary = class extends React.Component {
38
37
  }
39
38
  };
40
39
  function PageInspectorContent(t0) {
41
- const $ = c(8);
42
- const { page, pageRecord, runtimeBasePath } = t0;
40
+ const $ = c(12);
41
+ const { page, runtimeBasePath } = t0;
43
42
  switch (page.kind) {
44
43
  case "curated": {
45
44
  let t1;
@@ -51,31 +50,45 @@ function PageInspectorContent(t0) {
51
50
  }
52
51
  case "singleton": {
53
52
  let t1;
54
- if ($[1] !== page.layoutId || $[2] !== runtimeBasePath) {
55
- t1 = /* @__PURE__ */ jsx(SingletonPageInspector, {
53
+ if ($[1] !== runtimeBasePath) {
54
+ t1 = { runtimeBasePath };
55
+ $[1] = runtimeBasePath;
56
+ $[2] = t1;
57
+ } else t1 = $[2];
58
+ let t2;
59
+ if ($[3] !== page.layoutId || $[4] !== t1) {
60
+ t2 = /* @__PURE__ */ jsx(LayoutPageOverview, {
56
61
  layoutId: page.layoutId,
57
- runtimeBasePath
62
+ target: t1
58
63
  });
59
- $[1] = page.layoutId;
60
- $[2] = runtimeBasePath;
61
- $[3] = t1;
62
- } else t1 = $[3];
63
- return t1;
64
+ $[3] = page.layoutId;
65
+ $[4] = t1;
66
+ $[5] = t2;
67
+ } else t2 = $[5];
68
+ return t2;
64
69
  }
65
70
  case "derived": {
66
71
  let t1;
67
- if ($[4] !== page.layoutId || $[5] !== pageRecord || $[6] !== runtimeBasePath) {
68
- t1 = /* @__PURE__ */ jsx(DerivedPageInspector, {
72
+ if ($[6] !== page.layoutId || $[7] !== runtimeBasePath) {
73
+ t1 = {
74
+ runtimeBasePath,
75
+ derivedLayoutId: page.layoutId
76
+ };
77
+ $[6] = page.layoutId;
78
+ $[7] = runtimeBasePath;
79
+ $[8] = t1;
80
+ } else t1 = $[8];
81
+ let t2;
82
+ if ($[9] !== page.layoutId || $[10] !== t1) {
83
+ t2 = /* @__PURE__ */ jsx(LayoutPageOverview, {
69
84
  layoutId: page.layoutId,
70
- pageRecord,
71
- runtimeBasePath
85
+ target: t1
72
86
  });
73
- $[4] = page.layoutId;
74
- $[5] = pageRecord;
75
- $[6] = runtimeBasePath;
76
- $[7] = t1;
77
- } else t1 = $[7];
78
- return t1;
87
+ $[9] = page.layoutId;
88
+ $[10] = t1;
89
+ $[11] = t2;
90
+ } else t2 = $[11];
91
+ return t2;
79
92
  }
80
93
  }
81
94
  }
@@ -85,8 +98,8 @@ function PageInspectorContent(t0) {
85
98
  * overview, and the name's header goes back to it.
86
99
  */
87
100
  function PageInspector(t0) {
88
- const $ = c(27);
89
- const { page, owner, pageRecord, runtimeBasePath } = t0;
101
+ const $ = c(26);
102
+ const { page, owner, runtimeBasePath } = t0;
90
103
  const { pathname } = useLocation();
91
104
  let t1;
92
105
  if ($[0] !== owner) {
@@ -140,51 +153,49 @@ function PageInspector(t0) {
140
153
  $[10] = t6;
141
154
  } else t6 = $[10];
142
155
  let t7;
143
- if ($[11] !== page || $[12] !== pageRecord || $[13] !== runtimeBasePath) {
156
+ if ($[11] !== page || $[12] !== runtimeBasePath) {
144
157
  t7 = /* @__PURE__ */ jsx(PageInspectorContent, {
145
158
  page,
146
- pageRecord,
147
159
  runtimeBasePath
148
160
  });
149
161
  $[11] = page;
150
- $[12] = pageRecord;
151
- $[13] = runtimeBasePath;
152
- $[14] = t7;
153
- } else t7 = $[14];
162
+ $[12] = runtimeBasePath;
163
+ $[13] = t7;
164
+ } else t7 = $[13];
154
165
  let t8;
155
- if ($[15] !== t6 || $[16] !== t7) {
166
+ if ($[14] !== t6 || $[15] !== t7) {
156
167
  t8 = /* @__PURE__ */ jsx(React.Suspense, {
157
168
  fallback: t6,
158
169
  children: t7
159
170
  });
160
- $[15] = t6;
161
- $[16] = t7;
162
- $[17] = t8;
163
- } else t8 = $[17];
171
+ $[14] = t6;
172
+ $[15] = t7;
173
+ $[16] = t8;
174
+ } else t8 = $[16];
164
175
  let t9;
165
- if ($[18] !== t5 || $[19] !== t8) {
176
+ if ($[17] !== t5 || $[18] !== t8) {
166
177
  t9 = /* @__PURE__ */ jsx(PageInspectorBoundary, { children: t8 }, t5);
167
- $[18] = t5;
168
- $[19] = t8;
169
- $[20] = t9;
170
- } else t9 = $[20];
178
+ $[17] = t5;
179
+ $[18] = t8;
180
+ $[19] = t9;
181
+ } else t9 = $[19];
171
182
  let t10;
172
- if ($[21] !== owner || $[22] !== t9) {
183
+ if ($[20] !== owner || $[21] !== t9) {
173
184
  t10 = /* @__PURE__ */ jsx(CanvasInspectorBody, { children: /* @__PURE__ */ jsx(PreviewEditingOwnerContext, {
174
185
  value: owner,
175
186
  children: t9
176
187
  }) });
177
- $[21] = owner;
178
- $[22] = t9;
179
- $[23] = t10;
180
- } else t10 = $[23];
188
+ $[20] = owner;
189
+ $[21] = t9;
190
+ $[22] = t10;
191
+ } else t10 = $[22];
181
192
  let t11;
182
- if ($[24] !== t10 || $[25] !== t4) {
193
+ if ($[23] !== t10 || $[24] !== t4) {
183
194
  t11 = /* @__PURE__ */ jsxs(Fragment, { children: [t4, t10] });
184
- $[24] = t10;
185
- $[25] = t4;
186
- $[26] = t11;
187
- } else t11 = $[26];
195
+ $[23] = t10;
196
+ $[24] = t4;
197
+ $[25] = t11;
198
+ } else t11 = $[25];
188
199
  return t11;
189
200
  }
190
201
  function _temp() {
@@ -61,14 +61,14 @@ function CuratedPageSkeleton() {
61
61
  } else t0 = $[0];
62
62
  return t0;
63
63
  }
64
- /** A layout page's blocks and notice. */
64
+ /** A layout page's blocks. */
65
65
  function LayoutPageSkeleton() {
66
66
  const $ = c(1);
67
67
  let t0;
68
68
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
69
- t0 = /* @__PURE__ */ jsx(LoadingPage, { children: /* @__PURE__ */ jsxs("div", {
70
- className: "flex flex-col gap-4 px-2 pt-4",
71
- children: [/* @__PURE__ */ jsx(BlocksGroupSkeleton, {}), /* @__PURE__ */ jsx(Skeleton, { className: "h-20 w-full rounded-lg" })]
69
+ t0 = /* @__PURE__ */ jsx(LoadingPage, { children: /* @__PURE__ */ jsx("div", {
70
+ className: "px-2 pt-4",
71
+ children: /* @__PURE__ */ jsx(BlocksGroupSkeleton, {})
72
72
  }) });
73
73
  $[0] = t0;
74
74
  } else t0 = $[0];
@@ -1,7 +1,7 @@
1
1
  import { canvasStore } from "./canvasStore.js";
2
2
  import { ViewportContinuityContext, captureViewportAnchor, resolveViewportAnchor } from "../preview/viewportContinuity.js";
3
3
  import { canvasPageIframe } from "../preview/previewPageFrame.js";
4
- import { canvasBlockOverlap } from "./canvasFrameDocument.js";
4
+ import { canvasSeamCover } from "./canvasFrameDocument.js";
5
5
  import { revealScrollDelta } from "../preview/selectionReveal.js";
6
6
  import { CANVAS_WHEEL_ZOOM_RATE, ZOOM_STRETCH, canvasMaximumScale, canvasMinimumScale, canvasOverview, canvasVerticalRail, canvasWheelDelta, constrainCanvasCamera, findCanvasSnapTarget, fitCanvasPage, isCanvasCameraSnapped, isCanvasPageScale, isInCanvasSnapWindow, placeCanvasPageAnchor, snapCanvasZoom, stretchCanvasZoom, unstretchCanvasZoom, zoomCanvasAt } from "./canvasCamera.js";
7
7
  import { createCanvasFlight, createCanvasPan } from "./canvasFlight.js";
@@ -73,7 +73,7 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
73
73
  for (const name of CAMERA_PROPERTIES) element.style.removeProperty(name);
74
74
  delete element.dataset.canvasPan;
75
75
  delete element.dataset.canvasPromoted;
76
- delete element.dataset.canvasBlockOverlap;
76
+ delete element.dataset.canvasSeamCover;
77
77
  };
78
78
  }, []);
79
79
  /**
@@ -117,10 +117,19 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
117
117
  };
118
118
  };
119
119
  let viewportSize = measureViewport();
120
- const measureContent = () => ({
121
- width: rowRef.current?.width ?? content.offsetWidth,
122
- height: content.offsetHeight
123
- });
120
+ const page = initialTargetRef.current;
121
+ const targets = () => rowRef.current?.targets ?? (page ? [{
122
+ ...page,
123
+ key: "initial"
124
+ }] : []);
125
+ const measureContent = () => {
126
+ const widths = targets().map((target) => target.width);
127
+ return {
128
+ width: rowRef.current?.width ?? content.offsetWidth,
129
+ height: content.offsetHeight,
130
+ pageWidth: widths.length ? Math.min(...widths) : void 0
131
+ };
132
+ };
124
133
  let contentSize = measureContent();
125
134
  let minimumScale = canvasMinimumScale(viewportSize, contentSize);
126
135
  const updateGeometry = (nextViewport = measureViewport(), nextContent = measureContent()) => {
@@ -128,11 +137,6 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
128
137
  contentSize = nextContent;
129
138
  minimumScale = canvasMinimumScale(viewportSize, contentSize);
130
139
  };
131
- const page = initialTargetRef.current;
132
- const targets = () => rowRef.current?.targets ?? (page ? [{
133
- ...page,
134
- key: "initial"
135
- }] : []);
136
140
  const targetOf = (key) => key == null ? void 0 : targets().find((candidate) => candidate.key === key);
137
141
  let stretch;
138
142
  let zoomEnd = 0;
@@ -285,10 +289,10 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
285
289
  };
286
290
  const paintAtRest = () => {
287
291
  if (settle) return;
288
- const overlap = String(canvasBlockOverlap(camera.scale, ownerWindow.devicePixelRatio));
292
+ const seamCover = String(canvasSeamCover(camera.scale, ownerWindow.devicePixelRatio));
289
293
  const zoom = String(camera.scale);
290
294
  for (const element of [viewport, ...mirrors.current]) {
291
- if (element.dataset.canvasBlockOverlap !== overlap) element.dataset.canvasBlockOverlap = overlap;
295
+ if (element.dataset.canvasSeamCover !== seamCover) element.dataset.canvasSeamCover = seamCover;
292
296
  if (element.style.getPropertyValue("--canvas-rest-zoom") !== zoom) element.style.setProperty("--canvas-rest-zoom", zoom);
293
297
  }
294
298
  };
@@ -422,6 +426,7 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
422
426
  };
423
427
  animation = requestAnimationFrame(animate);
424
428
  };
429
+ let syncedTargets = targets();
425
430
  flightControls.current = {
426
431
  flyTo: startFlight,
427
432
  reveal: (element, immediate) => {
@@ -447,6 +452,8 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
447
452
  syncRow: () => {
448
453
  const key = rowRef.current?.selected ?? null;
449
454
  const destination = targetOf(key);
455
+ const previousTargets = syncedTargets;
456
+ syncedTargets = targets();
450
457
  if (key !== requested) {
451
458
  requested = key;
452
459
  selection = key;
@@ -459,6 +466,20 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
459
466
  else if (page.left !== flight.page.left || page.width !== flight.page.width) startFlight(page.key);
460
467
  return;
461
468
  }
469
+ const previous = previousTargets[syncedTargets.findIndex((candidate) => candidate.key === key)];
470
+ if (destination && previous?.key === key && previous.left !== destination.left && previous.width === destination.width && selection === key && !flight && isCanvasCameraSnapped(rest(target), viewportSize, previous)) {
471
+ updateGeometry();
472
+ const fit = fitCanvasPage(viewportSize, destination);
473
+ const next = {
474
+ ...fit,
475
+ y: rescaleY(restoredCamera ?? target, fit.scale)
476
+ };
477
+ if (restoredCamera || fittingInitialPage) restoredCamera = next;
478
+ fittingInitialPage = false;
479
+ camera = constrain(camera, true);
480
+ applyCamera(next, true);
481
+ return;
482
+ }
462
483
  if (destination && selection === key && !flight && !fittingInitialPage && !isCanvasCameraSnapped(rest(target), viewportSize, destination)) startFlight(destination.key);
463
484
  },
464
485
  fitAll: startOverviewFlight
@@ -511,7 +532,7 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
511
532
  const previousInsets = insets;
512
533
  const nextViewport = measureViewport();
513
534
  const nextContent = measureContent();
514
- if (insets.left === previousInsets.left && insets.top === previousInsets.top && nextViewport.width === viewportSize.width && nextViewport.height === viewportSize.height && nextContent.width === contentSize.width && nextContent.height === contentSize.height) return;
535
+ if (insets.left === previousInsets.left && insets.top === previousInsets.top && nextViewport.width === viewportSize.width && nextViewport.height === viewportSize.height && nextContent.width === contentSize.width && nextContent.height === contentSize.height && nextContent.pageWidth === contentSize.pageWidth) return;
515
536
  const wasFitted = isOverview(target);
516
537
  gesture = void 0;
517
538
  const held = nextViewport.width !== viewportSize.width && !flight && !fittingInitialPage ? targetOf(selection) : void 0;
@@ -767,7 +788,7 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
767
788
  ownerWindow.removeEventListener("blur", releaseSpace);
768
789
  delete viewport.dataset.canvasPan;
769
790
  delete viewport.dataset.canvasPromoted;
770
- delete viewport.dataset.canvasBlockOverlap;
791
+ delete viewport.dataset.canvasSeamCover;
771
792
  paintMirror.current = null;
772
793
  };
773
794
  }, [workspaceKey, continuity]);
@@ -12,6 +12,7 @@ import * as React from "react";
12
12
  import { jsx } from "react/jsx-runtime";
13
13
 
14
14
  //#region src/features/page/CuratedPageContent.tsx
15
+ /** A block read with its bundle, rendered by its definition's code as a page shows it. */
15
16
  function PageBlock(t0) {
16
17
  const $ = c(19);
17
18
  const { blockId, mode } = t0;
@@ -177,4 +178,4 @@ function _temp(block) {
177
178
  }
178
179
 
179
180
  //#endregion
180
- export { CuratedPageContent };
181
+ export { CuratedPageContent, PageBlock };
@@ -0,0 +1,52 @@
1
+ import { reads, useRead } from "../../lib/studio-reads.js";
2
+ import { BlockErrorBoundary } from "../preview/components/BlockErrorBoundary.js";
3
+ import { PageBlock } from "./CuratedPageContent.js";
4
+ import { c } from "react/compiler-runtime";
5
+ import { jsx } from "react/jsx-runtime";
6
+
7
+ //#region src/features/page/UnplacedBlockContent.tsx
8
+ /**
9
+ * A block placed nowhere, alone, as a page would show it: the look document's Block Definition
10
+ * mode (ADR 0032). Its bundle is read like a page's block, so it renders and hydrates as one.
11
+ * Thumbnails render a Block Definition their own way (`BlockPeek`); only the block render is
12
+ * shared.
13
+ */
14
+ function UnplacedBlockContent(t0) {
15
+ const $ = c(8);
16
+ const { blockId } = t0;
17
+ let t1;
18
+ if ($[0] !== blockId) {
19
+ t1 = reads.blockBundle(blockId);
20
+ $[0] = blockId;
21
+ $[1] = t1;
22
+ } else t1 = $[1];
23
+ const { block } = useRead(t1);
24
+ let t2;
25
+ if ($[2] !== blockId) {
26
+ t2 = /* @__PURE__ */ jsx(PageBlock, {
27
+ blockId,
28
+ mode: "site"
29
+ });
30
+ $[2] = blockId;
31
+ $[3] = t2;
32
+ } else t2 = $[3];
33
+ let t3;
34
+ if ($[4] !== block.type || $[5] !== blockId || $[6] !== t2) {
35
+ t3 = /* @__PURE__ */ jsx("main", {
36
+ className: "flex flex-col",
37
+ children: /* @__PURE__ */ jsx(BlockErrorBoundary, {
38
+ blockId,
39
+ blockType: block.type,
40
+ children: t2
41
+ })
42
+ });
43
+ $[4] = block.type;
44
+ $[5] = blockId;
45
+ $[6] = t2;
46
+ $[7] = t3;
47
+ } else t3 = $[7];
48
+ return t3;
49
+ }
50
+
51
+ //#endregion
52
+ export { UnplacedBlockContent };