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.
- package/dist/core/editing/createEditableBlock.js +1077 -1681
- package/dist/core/editing/fieldSlot.js +251 -0
- package/dist/core/editing/useFieldSlot.js +159 -0
- package/dist/core/layoutContext.d.ts +2 -0
- package/dist/core/layoutContext.js +27 -1
- package/dist/features/canvas/CanvasPageFrame.js +2 -2
- package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -1
- package/dist/features/canvas/canvasCameraController.js +595 -0
- package/dist/features/canvas/useCanvasCamera.js +141 -587
- package/dist/features/canvas/useCanvasFrame.js +1 -1
- package/dist/features/page/DerivedPageContent.js +4 -8
- package/dist/features/preview/components/AssetLightbox.js +6 -65
- package/dist/features/preview/components/CanvasPreview.js +2 -2
- package/dist/features/preview/components/Frame.js +3 -3
- package/dist/features/preview/components/ItemFieldsEditor.js +376 -460
- package/dist/features/preview/components/Overlays.js +4 -9
- package/dist/features/preview/components/PreviewPanel.js +3 -3
- package/dist/features/preview/components/RemovedBlockPlaceholder.js +2 -2
- package/dist/features/preview/components/SelectionEditor.js +285 -339
- package/dist/features/preview/components/ZoomableImage.js +105 -0
- package/dist/features/preview/components/contentFieldSchema.js +3 -1
- package/dist/features/preview/components/useFieldWriter.js +30 -51
- package/dist/features/preview/components/useRecordView.js +3 -3
- package/dist/features/preview/overlayMessages.js +20 -58
- package/dist/features/preview/previewStore.js +6 -123
- package/dist/features/preview/repeatableItemPath.js +47 -0
- package/dist/features/provider/AuthenticatedCamoxProvider.js +75 -63
- package/dist/features/renderer/RendererApp.js +6 -6
- package/dist/features/renderer/RendererFrames.js +2 -2
- package/dist/features/renderer/rendererHost.js +1 -1
- package/dist/features/routes/pageRuntime.d.ts +8 -12
- package/dist/features/routes/pageRuntime.js +26 -106
- package/dist/features/runtime/pageApp.js +1 -1
- package/dist/features/runtime/pageRead.js +105 -0
- package/dist/features/runtime/reader.d.ts +25 -0
- package/dist/features/runtime/reader.js +142 -0
- package/dist/features/runtime/runtime.d.ts +9 -3
- package/dist/features/runtime/runtime.js +608 -776
- package/dist/features/sdkBundle/buildSdkBundle.d.ts +5 -0
- package/dist/features/sdkBundle/buildSdkBundle.js +9 -3
- package/dist/features/studio/components/ChatWidget.js +137 -121
- package/dist/features/studio/components/ClearThread.js +121 -0
- package/dist/features/studio/components/DeleteDraftDialog.js +67 -65
- package/dist/features/studio/components/DraftBar.js +60 -49
- package/dist/features/studio/components/DraftNotices.js +149 -0
- package/dist/features/studio/components/DraftsControl.js +217 -180
- package/dist/features/studio/components/DraftsSheet.js +446 -0
- package/dist/features/studio/components/PublishedTab.js +511 -0
- package/dist/features/studio/components/ReviewDraftDialog.js +104 -89
- package/dist/features/studio/components/SheetTable.js +46 -0
- package/dist/features/studio/components/Specialists.js +1 -1
- package/dist/features/studio/components/ThreadMessages.js +227 -176
- package/dist/features/studio/draftLabel.js +15 -1
- package/dist/features/studio/draftNotice.js +1 -0
- package/dist/features/studio/showInCanvas.js +9 -19
- package/dist/features/studio/studioStore.js +5 -5
- package/dist/features/studio/useArchiveDraft.js +60 -0
- package/dist/features/studio/useEditorSelection.js +8 -19
- package/dist/features/studio/useRestoreDraft.js +70 -0
- package/dist/features/studio/viewSwitch.js +19 -11
- package/dist/lib/draft-scope.d.ts +1 -1
- package/dist/lib/draft-scope.js +6 -3
- package/dist/lib/queries.js +12 -1
- package/dist/lib/studio-reads.js +22 -0
- package/dist/lib/use-project-room.js +19 -13
- package/dist/lib/use-thread.js +1 -1
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +4 -4
- package/dist/core/hooks/useFieldSelection.js +0 -67
- package/dist/core/hooks/useIsEditable.js +0 -21
- 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
|
|
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<
|
|
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<
|
|
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?: {
|