camox 0.75.0 → 0.76.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/core/editing/createEditableBlock.js +1077 -1681
  2. package/dist/core/editing/fieldSlot.js +251 -0
  3. package/dist/core/editing/useFieldSlot.js +159 -0
  4. package/dist/core/layoutContext.d.ts +2 -0
  5. package/dist/core/layoutContext.js +27 -1
  6. package/dist/features/canvas/CanvasPageFrame.js +2 -2
  7. package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -1
  8. package/dist/features/canvas/canvasCameraController.js +595 -0
  9. package/dist/features/canvas/useCanvasCamera.js +141 -587
  10. package/dist/features/canvas/useCanvasFrame.js +1 -1
  11. package/dist/features/page/DerivedPageContent.js +4 -8
  12. package/dist/features/preview/components/AssetLightbox.js +6 -65
  13. package/dist/features/preview/components/CanvasPreview.js +2 -2
  14. package/dist/features/preview/components/Frame.js +3 -3
  15. package/dist/features/preview/components/ItemFieldsEditor.js +376 -460
  16. package/dist/features/preview/components/Overlays.js +4 -9
  17. package/dist/features/preview/components/PreviewPanel.js +3 -3
  18. package/dist/features/preview/components/RemovedBlockPlaceholder.js +2 -2
  19. package/dist/features/preview/components/SelectionEditor.js +285 -339
  20. package/dist/features/preview/components/ZoomableImage.js +105 -0
  21. package/dist/features/preview/components/contentFieldSchema.js +3 -1
  22. package/dist/features/preview/components/useFieldWriter.js +30 -51
  23. package/dist/features/preview/components/useRecordView.js +3 -3
  24. package/dist/features/preview/overlayMessages.js +20 -58
  25. package/dist/features/preview/previewStore.js +6 -123
  26. package/dist/features/preview/repeatableItemPath.js +47 -0
  27. package/dist/features/provider/AuthenticatedCamoxProvider.js +75 -63
  28. package/dist/features/renderer/RendererApp.js +6 -6
  29. package/dist/features/renderer/RendererFrames.js +2 -2
  30. package/dist/features/renderer/rendererHost.js +1 -1
  31. package/dist/features/routes/pageRuntime.d.ts +8 -12
  32. package/dist/features/routes/pageRuntime.js +26 -106
  33. package/dist/features/runtime/pageApp.js +1 -1
  34. package/dist/features/runtime/pageRead.js +105 -0
  35. package/dist/features/runtime/reader.d.ts +25 -0
  36. package/dist/features/runtime/reader.js +142 -0
  37. package/dist/features/runtime/runtime.d.ts +9 -3
  38. package/dist/features/runtime/runtime.js +608 -776
  39. package/dist/features/sdkBundle/buildSdkBundle.d.ts +5 -0
  40. package/dist/features/sdkBundle/buildSdkBundle.js +9 -3
  41. package/dist/features/studio/components/ChatWidget.js +137 -121
  42. package/dist/features/studio/components/ClearThread.js +121 -0
  43. package/dist/features/studio/components/DeleteDraftDialog.js +67 -65
  44. package/dist/features/studio/components/DraftBar.js +60 -49
  45. package/dist/features/studio/components/DraftNotices.js +149 -0
  46. package/dist/features/studio/components/DraftsControl.js +217 -180
  47. package/dist/features/studio/components/DraftsSheet.js +446 -0
  48. package/dist/features/studio/components/PublishedTab.js +511 -0
  49. package/dist/features/studio/components/ReviewDraftDialog.js +104 -89
  50. package/dist/features/studio/components/SheetTable.js +46 -0
  51. package/dist/features/studio/components/Specialists.js +1 -1
  52. package/dist/features/studio/components/ThreadMessages.js +227 -176
  53. package/dist/features/studio/draftLabel.js +15 -1
  54. package/dist/features/studio/draftNotice.js +1 -0
  55. package/dist/features/studio/showInCanvas.js +9 -19
  56. package/dist/features/studio/studioStore.js +5 -5
  57. package/dist/features/studio/useArchiveDraft.js +60 -0
  58. package/dist/features/studio/useEditorSelection.js +8 -19
  59. package/dist/features/studio/useRestoreDraft.js +70 -0
  60. package/dist/features/studio/viewSwitch.js +19 -11
  61. package/dist/lib/draft-scope.d.ts +1 -1
  62. package/dist/lib/draft-scope.js +6 -3
  63. package/dist/lib/queries.js +12 -1
  64. package/dist/lib/studio-reads.js +22 -0
  65. package/dist/lib/use-project-room.js +19 -13
  66. package/dist/lib/use-thread.js +1 -1
  67. package/dist/package.js +1 -1
  68. package/dist/studio.css +1 -1
  69. package/package.json +4 -4
  70. package/dist/core/hooks/useFieldSelection.js +0 -67
  71. package/dist/core/hooks/useIsEditable.js +0 -21
  72. package/dist/core/hooks/useOverlayMessage.js +0 -70
@@ -0,0 +1,142 @@
1
+ import { draftNamedBy } from "../../lib/draft-scope.js";
2
+ import { buildClearServerAuthCookieHeader, getLookToken, getServerAuthCookieHeader } from "../../lib/server-auth-cookie.js";
3
+ import { createServerApiClient, draftRefusalNotice, isAuthSessionError } from "../routes/pageRuntime.js";
4
+ import { DRAFT_SEARCH_PARAM } from "@camox/api-contract/drafts";
5
+
6
+ //#region src/features/runtime/reader.ts
7
+ /** The content port's production adapter: the API at `apiUrl`, over oRPC. */
8
+ function apiContent(apiUrl) {
9
+ return (access) => createServerApiClient(apiUrl, access);
10
+ }
11
+ function contentOf(options) {
12
+ return options.content ?? (options.apiUrl ? apiContent(options.apiUrl) : void 0);
13
+ }
14
+ /**
15
+ * Whether a request may see what only it sees, so no shared cache keeps its response (ADR 0022).
16
+ * Known before any read, so a cache can decide before the runtime answers.
17
+ */
18
+ function isPrivateRequest(request) {
19
+ return !!getServerAuthCookieHeader(request.headers) || draftNamedBy(request.url) !== null;
20
+ }
21
+ /**
22
+ * The request's Reader: a Member when the API confirms its session for the project, which it
23
+ * asks once, else a Visitor. A session the API refuses is cleared. Without a project or a way to
24
+ * read content, nobody is a Member.
25
+ */
26
+ async function resolveReader(request, options) {
27
+ const content = contentOf(options);
28
+ const session = getServerAuthCookieHeader(request.headers);
29
+ const named = draftNamedBy(request.url) ?? void 0;
30
+ const isPrivate = isPrivateRequest(request);
31
+ if (!content || !options.projectUuid || !session) return visitor(content, options, {
32
+ named,
33
+ private: isPrivate
34
+ });
35
+ let member;
36
+ try {
37
+ member = await content({ credential: { session } }).projects.getByUuid({ projectUuid: options.projectUuid });
38
+ } catch (error) {
39
+ if (!isAuthSessionError(error)) throw error;
40
+ console.warn("[camox] Ignoring stale camox_auth_cookie.");
41
+ return visitor(content, options, {
42
+ named,
43
+ private: isPrivate,
44
+ setCookie: buildClearServerAuthCookieHeader()
45
+ });
46
+ }
47
+ const credential = { session };
48
+ const api = ({ draftId, locale } = {}) => content({
49
+ credential,
50
+ draftId,
51
+ locale
52
+ });
53
+ return withLocales(options, {
54
+ member,
55
+ draftId: named,
56
+ private: isPrivate,
57
+ setCookie: void 0,
58
+ api,
59
+ read: async (read) => {
60
+ if (!named) return { value: await read(void 0) };
61
+ try {
62
+ return {
63
+ value: await read(named),
64
+ draftId: named
65
+ };
66
+ } catch (error) {
67
+ const notice = draftRefusalNotice(error, named);
68
+ if (notice === void 0) throw error;
69
+ return {
70
+ value: await read(void 0),
71
+ refusedDraft: { notice }
72
+ };
73
+ }
74
+ }
75
+ });
76
+ }
77
+ /**
78
+ * A Visitor's Reader, for what reads Live whoever asks (sitemaps, llms.txt, Markdown): no
79
+ * session check, no credential.
80
+ */
81
+ function visitorReader(options) {
82
+ return visitor(contentOf(options), options, {
83
+ named: void 0,
84
+ private: false
85
+ });
86
+ }
87
+ /**
88
+ * The look document's Reader (ADR 0032): the look token the request's cookie carries, for the
89
+ * Draft the URL names. Null without both.
90
+ */
91
+ function lookReader(request, options) {
92
+ const content = contentOf(options);
93
+ const lookToken = getLookToken(request.headers);
94
+ const draftId = new URL(request.url).searchParams.get(DRAFT_SEARCH_PARAM) || void 0;
95
+ if (!content || !lookToken || !draftId) return null;
96
+ const credential = { lookToken };
97
+ return withLocales(options, {
98
+ member: void 0,
99
+ draftId,
100
+ private: true,
101
+ setCookie: void 0,
102
+ api: ({ locale } = {}) => content({
103
+ credential,
104
+ draftId,
105
+ locale
106
+ }),
107
+ read: async (read) => ({
108
+ value: await read(draftId),
109
+ draftId
110
+ })
111
+ });
112
+ }
113
+ function visitor(content, options, { named, private: isPrivate, setCookie }) {
114
+ const api = ({ locale } = {}) => {
115
+ if (!content) throw new Error("Camox has no content to read: the runtime names no API.");
116
+ return content({ locale });
117
+ };
118
+ return withLocales(options, {
119
+ member: void 0,
120
+ draftId: void 0,
121
+ private: isPrivate,
122
+ setCookie,
123
+ api,
124
+ read: async (read) => ({
125
+ value: await read(void 0),
126
+ ...named && { refusedDraft: { notice: null } }
127
+ })
128
+ });
129
+ }
130
+ function withLocales(options, reader) {
131
+ return {
132
+ ...reader,
133
+ locales: async () => {
134
+ const projectUuid = options.projectUuid;
135
+ const { value } = await reader.read((draftId) => reader.api({ draftId }).locales.list({ projectUuid }));
136
+ return value;
137
+ }
138
+ };
139
+ }
140
+
141
+ //#endregion
142
+ export { apiContent, isPrivateRequest, lookReader, resolveReader, visitorReader };
@@ -3,9 +3,10 @@ import { AlternatePath, LocaleView } from "../../lib/locale-path.js";
3
3
  import { AnyLayoutLoaderResult } from "../../core/createLayout.js";
4
4
  import { CamoxApp } from "../../core/createApp.js";
5
5
  import { AnalyticsProviders } from "./analytics.js";
6
+ import { Content, ContentClient } from "./reader.js";
6
7
  import { RuntimeOwnedRouteKind } from "./runtimeRoutes.js";
7
8
  import { StudioRenderInput } from "./studioApp.js";
8
- import { DraftRead, MemberProject, PageHead, createServerApiClient } from "../routes/pageRuntime.js";
9
+ import { DraftRead, MemberProject, PageHead } from "../routes/pageRuntime.js";
9
10
  import { LookPlaceholderHeight } from "@camox/api-contract/drafts";
10
11
  import { UseHeadInput } from "unhead/types";
11
12
  //#region src/features/runtime/runtime.d.ts
@@ -47,7 +48,7 @@ export interface PageRenderInput extends DraftRead {
47
48
  */
48
49
  lookLayout?: {
49
50
  layoutId: string;
50
- layout: Awaited<ReturnType<ReturnType<typeof createServerApiClient>["layouts"]["getUnplaced"]>>["layout"];
51
+ layout: Awaited<ReturnType<ContentClient["layouts"]["getUnplaced"]>>["layout"];
51
52
  placeholder: LookPlaceholderHeight;
52
53
  path: string;
53
54
  projectName: string;
@@ -74,7 +75,7 @@ export interface PageRenderInput extends DraftRead {
74
75
  projectName: string;
75
76
  };
76
77
  result?: AnyLayoutLoaderResult;
77
- layout: Awaited<ReturnType<ReturnType<typeof createServerApiClient>["layouts"]["get"]>>["layout"];
78
+ layout: Awaited<ReturnType<ContentClient["layouts"]["get"]>>["layout"];
78
79
  };
79
80
  apiUrl: string;
80
81
  authenticationUrl: string;
@@ -97,6 +98,11 @@ export interface PageRenderInput extends DraftRead {
97
98
  }
98
99
  export interface RuntimeOptions {
99
100
  apiUrl?: string;
101
+ /**
102
+ * Where the runtime reads content, as each request's Reader sees it. Without it, the API at
103
+ * `apiUrl`. Tests read an in-memory one.
104
+ */
105
+ content?: Content;
100
106
  authenticationUrl?: string;
101
107
  /** Where the browser loads each block from, so a page can preload the blocks it renders. */
102
108
  blockPreloads?: {