@agent-native/core 0.101.7 → 0.101.11
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +28 -0
- package/corpus/core/docs/content/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/ar-SA/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/de-DE/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/es-ES/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/fr-FR/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/hi-IN/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/ja-JP/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/ko-KR/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/pt-BR/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/zh-CN/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/zh-TW/deployment.mdx +9 -7
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/client.ts +23 -1
- package/corpus/core/src/a2a/handlers.ts +65 -1
- package/corpus/core/src/a2a/server.ts +124 -0
- package/corpus/core/src/a2a/task-store.ts +253 -0
- package/corpus/core/src/a2a/types.ts +26 -0
- package/corpus/core/src/agent/production-agent.ts +5 -2
- package/corpus/core/src/client/review/ReviewCommentComposer.tsx +9 -1
- package/corpus/core/src/client/review/ReviewThreadPanel.tsx +17 -2
- package/corpus/core/src/client/settings/SettingsPanel.tsx +41 -21
- package/corpus/core/src/client/settings/useBuilderStatus.ts +28 -9
- package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +2 -7
- package/corpus/core/src/mcp/builtin-tools.ts +25 -1
- package/corpus/core/src/scripts/call-agent.ts +22 -3
- package/corpus/core/src/server/agent-chat-plugin.ts +86 -1
- package/corpus/core/src/server/auth.ts +25 -1
- package/corpus/core/src/server/builder-browser.ts +353 -1
- package/corpus/core/src/server/core-routes-plugin.ts +601 -223
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +25 -0
- package/corpus/templates/calendar/app/components/calendar/DayView.tsx +80 -1
- package/corpus/templates/calendar/app/components/calendar/EventCard.tsx +28 -3
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +5 -1
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +30 -3
- package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +196 -0
- package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +115 -1
- package/corpus/templates/calendar/app/lib/out-of-office.ts +45 -0
- package/corpus/templates/calendar/changelog/2026-07-14-out-of-office-blocks-now-sit-behind-meetings-and-event-stack.md +6 -0
- package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +23 -0
- package/corpus/templates/content/AGENTS.md +3 -2
- package/corpus/templates/content/actions/_builder-cms-intent-lookup.ts +87 -0
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +173 -25
- package/corpus/templates/content/actions/_builder-cms-source-adapter.ts +1 -0
- package/corpus/templates/content/actions/_builder-cms-write-adapter.ts +427 -18
- package/corpus/templates/content/actions/_builder-cms-write-client.ts +17 -73
- package/corpus/templates/content/actions/_builder-cms-write-settings.ts +27 -7
- package/corpus/templates/content/actions/_builder-source-execution-claim.ts +124 -0
- package/corpus/templates/content/actions/_builder-source-execution-preservation.ts +21 -0
- package/corpus/templates/content/actions/_builder-source-timings.ts +57 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +1041 -154
- package/corpus/templates/content/actions/_database-utils.ts +89 -12
- package/corpus/templates/content/actions/_preview-document-draft.ts +31 -0
- package/corpus/templates/content/actions/cancel-prepared-builder-source-update.ts +309 -0
- package/corpus/templates/content/actions/execute-builder-source-batch.ts +120 -49
- package/corpus/templates/content/actions/execute-builder-source-execution.ts +608 -264
- package/corpus/templates/content/actions/get-preview-document-draft.ts +26 -0
- package/corpus/templates/content/actions/materialize-builder-required-fields.ts +550 -0
- package/corpus/templates/content/actions/prepare-builder-source-execution.ts +112 -65
- package/corpus/templates/content/actions/prepare-builder-source-review.ts +463 -170
- package/corpus/templates/content/actions/preview-builder-source-review.ts +99 -0
- package/corpus/templates/content/actions/set-content-database-source-write-mode.ts +2 -2
- package/corpus/templates/content/actions/update-preview-document-draft.ts +153 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +27 -15
- package/corpus/templates/content/app/components/editor/MathRenderer.tsx +43 -0
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +260 -4
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +57 -5
- package/corpus/templates/content/app/components/editor/body-hydration.ts +27 -0
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +2353 -576
- package/corpus/templates/content/app/components/editor/database/settings.tsx +13 -10
- package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +358 -75
- package/corpus/templates/content/app/components/editor/extensions/NotionExtensions.tsx +78 -0
- package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +124 -29
- package/corpus/templates/content/app/components/editor/previewDocumentSaveRegistry.ts +2 -0
- package/corpus/templates/content/app/global.css +71 -1
- package/corpus/templates/content/app/hooks/use-content-database.ts +68 -0
- package/corpus/templates/content/app/hooks/use-documents.ts +53 -4
- package/corpus/templates/content/app/i18n/zh-TW.ts +38 -0
- package/corpus/templates/content/app/i18n-data.ts +450 -0
- package/corpus/templates/content/app/root.tsx +2 -0
- package/corpus/templates/content/changelog/2026-07-10-builder-backed-preview-edits-are-preserved-when-article-bodi.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-builder-cms-sources-can-now-be-enabled-for-guarded-staged-or.md +6 -0
- package/corpus/templates/content/changelog/2026-07-13-builder-connection-setup-is-now-available-directly-from-conn.md +6 -0
- package/corpus/templates/content/changelog/2026-07-13-builder-reviews-now-hide-already-applied-writes-detect-nativ.md +6 -0
- package/corpus/templates/content/changelog/2026-07-13-required-builder-publishing-fields-can-now-be-added-directly.md +6 -0
- package/corpus/templates/content/changelog/2026-07-13-you-can-now-cancel-a-prepared-builder-update-safely-before-i.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-builder-account-connection-now-remains-available-when-branch.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-builder-backed-articles-now-preserve-fifth-and-sixth-level-h.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-builder-sources-now-review-and-publish-rich-article-updates-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-builder-writes-now-stop-retries-when-reconciliation-is-needed.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-file-and-media-links-now-validate-before-saving.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-latex-equations-render-in-documents-public-pages-and-exports.md +6 -0
- package/corpus/templates/content/package.json +1 -0
- package/corpus/templates/content/parity/matrix.md +27 -25
- package/corpus/templates/content/parity/matrix.ts +50 -2
- package/corpus/templates/content/server/db/schema.ts +47 -0
- package/corpus/templates/content/server/plugins/auth.ts +1 -0
- package/corpus/templates/content/server/plugins/db.ts +53 -0
- package/corpus/templates/content/shared/api.ts +70 -1
- package/corpus/templates/content/shared/builder-mdx.ts +705 -15
- package/corpus/templates/content/shared/document-export.ts +296 -25
- package/corpus/templates/content/shared/inline-math.ts +128 -0
- package/corpus/templates/content/shared/math-rendering.ts +50 -0
- package/corpus/templates/content/shared/nfm.ts +20 -17
- package/corpus/templates/content/vite.config.ts +0 -1
- package/corpus/templates/design/app/components/design/ReadOnlyDesignBanner.tsx +52 -7
- package/corpus/templates/design/app/components/design/ReviewCommentsPanel.tsx +36 -4
- package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +4 -1
- package/corpus/templates/design/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/design/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/design/app/i18n/en-US.ts +1 -0
- package/corpus/templates/design/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/design/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/design/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/design/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/design/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/design/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/design/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +8 -0
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +11 -0
- package/corpus/templates/design/changelog/2026-07-14-reviewers-can-now-pin-comments-from-the-canvas-toolbar-targe.md +6 -0
- package/corpus/templates/design/changelog/2026-07-15-viewer-comment-controls-now-sit-inside-the-read-only-notice-.md +6 -0
- package/corpus/templates/design/shared/review-anchor.ts +48 -0
- package/corpus/templates/mail/.agents/skills/email-drafts/SKILL.md +17 -0
- package/corpus/templates/mail/AGENTS.md +21 -19
- package/corpus/templates/mail/actions/create-attachment-upload.ts +49 -0
- package/corpus/templates/mail/changelog/2026-07-14-connected-agents-can-now-securely-upload-local-files-for-mai.md +6 -0
- package/corpus/templates/mail/server/handlers/media.ts +84 -61
- package/corpus/templates/mail/server/lib/attachment-upload-ticket.ts +234 -0
- package/corpus/templates/mail/server/lib/mail-connector-catalog.ts +8 -4
- package/corpus/templates/mail/server/lib/media-upload.ts +114 -0
- package/corpus/templates/mail/server/plugins/auth.ts +9 -1
- package/corpus/templates/mail/server/routes/api/media/attachment-upload/[uploadId].put.ts +1 -0
- package/corpus/templates/plan/server/plan-mdx.ts +53 -7
- package/dist/a2a/client.d.ts +5 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +18 -1
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +57 -8
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +87 -1
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/task-store.d.ts +27 -0
- package/dist/a2a/task-store.d.ts.map +1 -1
- package/dist/a2a/task-store.js +216 -0
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/a2a/types.d.ts +24 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/agent/production-agent.d.ts +1 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +5 -2
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/client/review/ReviewCommentComposer.d.ts +2 -1
- package/dist/client/review/ReviewCommentComposer.d.ts.map +1 -1
- package/dist/client/review/ReviewCommentComposer.js +3 -3
- package/dist/client/review/ReviewCommentComposer.js.map +1 -1
- package/dist/client/review/ReviewThreadPanel.d.ts +9 -1
- package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -1
- package/dist/client/review/ReviewThreadPanel.js +6 -4
- package/dist/client/review/ReviewThreadPanel.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts +3 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +11 -4
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +8 -4
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +19 -6
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -1
- package/dist/client/setup-connections/BuilderConnectCard.js +2 -5
- package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/mcp/builtin-tools.d.ts.map +1 -1
- package/dist/mcp/builtin-tools.js +22 -3
- package/dist/mcp/builtin-tools.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/scripts/call-agent.d.ts +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +19 -1
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +71 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.d.ts +1 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +19 -2
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-browser.d.ts +78 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +246 -1
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +41 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +260 -14
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +25 -0
- package/docs/content/deployment.mdx +9 -7
- package/docs/content/locales/ar-SA/deployment.mdx +9 -7
- package/docs/content/locales/de-DE/deployment.mdx +9 -7
- package/docs/content/locales/es-ES/deployment.mdx +9 -7
- package/docs/content/locales/fr-FR/deployment.mdx +9 -7
- package/docs/content/locales/hi-IN/deployment.mdx +9 -7
- package/docs/content/locales/ja-JP/deployment.mdx +9 -7
- package/docs/content/locales/ko-KR/deployment.mdx +9 -7
- package/docs/content/locales/pt-BR/deployment.mdx +9 -7
- package/docs/content/locales/zh-CN/deployment.mdx +9 -7
- package/docs/content/locales/zh-TW/deployment.mdx +9 -7
- package/package.json +2 -2
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +25 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { findTrailingPlainInlineMath } from "@shared/inline-math";
|
|
1
2
|
import {
|
|
2
3
|
escapeHtml,
|
|
3
4
|
indentMarkdown,
|
|
@@ -10,6 +11,7 @@ import {
|
|
|
10
11
|
IconExternalLink,
|
|
11
12
|
IconFileText,
|
|
12
13
|
} from "@tabler/icons-react";
|
|
14
|
+
import { InputRule } from "@tiptap/core";
|
|
13
15
|
import type { Fragment, Node as ProseMirrorNode } from "@tiptap/pm/model";
|
|
14
16
|
import {
|
|
15
17
|
Mark,
|
|
@@ -21,6 +23,8 @@ import {
|
|
|
21
23
|
type NodeViewProps,
|
|
22
24
|
} from "@tiptap/react";
|
|
23
25
|
|
|
26
|
+
import { MathRenderer } from "../MathRenderer";
|
|
27
|
+
|
|
24
28
|
const BLOCK_ATOM_TAGS = [
|
|
25
29
|
"page",
|
|
26
30
|
"database",
|
|
@@ -452,6 +456,17 @@ function BlockAtomView({ node, extension }: NodeViewProps) {
|
|
|
452
456
|
const canOpenLocalPage = Boolean(pageLink && options.onOpenPageLink);
|
|
453
457
|
const externalUrl = safeExternalPageUrl(attrs.url || attrs.href || null);
|
|
454
458
|
|
|
459
|
+
if (tagName === "equation") {
|
|
460
|
+
return (
|
|
461
|
+
<NodeViewWrapper
|
|
462
|
+
className="content-equation"
|
|
463
|
+
data-latex={label || attrs.latex || ""}
|
|
464
|
+
>
|
|
465
|
+
<MathRenderer latex={label || attrs.latex || ""} displayMode={true} />
|
|
466
|
+
</NodeViewWrapper>
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
|
|
455
470
|
if (tagName === "page") {
|
|
456
471
|
const openPage = () => {
|
|
457
472
|
if (pageLink && options.onOpenPageLink) {
|
|
@@ -511,6 +526,36 @@ function BlockAtomView({ node, extension }: NodeViewProps) {
|
|
|
511
526
|
);
|
|
512
527
|
}
|
|
513
528
|
|
|
529
|
+
function InlineAtomView({ node }: NodeViewProps) {
|
|
530
|
+
const tagName = (node.attrs.tagName || "mention") as string;
|
|
531
|
+
const label = (node.attrs.label || "") as string;
|
|
532
|
+
const attrs = parseAttrsJson(node.attrs.attrsJson as string);
|
|
533
|
+
|
|
534
|
+
if (tagName === "math") {
|
|
535
|
+
const latex = label || attrs.latex || "";
|
|
536
|
+
return (
|
|
537
|
+
<NodeViewWrapper
|
|
538
|
+
as="span"
|
|
539
|
+
className="content-inline-equation"
|
|
540
|
+
contentEditable={false}
|
|
541
|
+
data-latex={latex}
|
|
542
|
+
>
|
|
543
|
+
<MathRenderer latex={latex} displayMode={false} />
|
|
544
|
+
</NodeViewWrapper>
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
return (
|
|
549
|
+
<NodeViewWrapper
|
|
550
|
+
as="span"
|
|
551
|
+
className="notion-inline-atom"
|
|
552
|
+
contentEditable={false}
|
|
553
|
+
>
|
|
554
|
+
{label || humanizeTag(tagName)}
|
|
555
|
+
</NodeViewWrapper>
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
|
|
514
559
|
export const NotionSpanMark = Mark.create({
|
|
515
560
|
name: "notionSpan",
|
|
516
561
|
|
|
@@ -975,6 +1020,35 @@ export const NotionInlineAtom = Node.create({
|
|
|
975
1020
|
atom: true,
|
|
976
1021
|
selectable: false,
|
|
977
1022
|
|
|
1023
|
+
addInputRules() {
|
|
1024
|
+
return [
|
|
1025
|
+
new InputRule({
|
|
1026
|
+
find: (text) => {
|
|
1027
|
+
const match = findTrailingPlainInlineMath(text);
|
|
1028
|
+
if (!match) return null;
|
|
1029
|
+
return {
|
|
1030
|
+
index: match.from,
|
|
1031
|
+
text: text.slice(match.from, match.to),
|
|
1032
|
+
data: { latex: match.latex },
|
|
1033
|
+
};
|
|
1034
|
+
},
|
|
1035
|
+
handler: ({ state, range, match }) => {
|
|
1036
|
+
const latex = match.data?.latex;
|
|
1037
|
+
if (typeof latex !== "string") return null;
|
|
1038
|
+
|
|
1039
|
+
const mathNode = state.schema.nodes.notionInlineAtom?.create({
|
|
1040
|
+
tagName: "math",
|
|
1041
|
+
attrsJson: "{}",
|
|
1042
|
+
label: latex,
|
|
1043
|
+
});
|
|
1044
|
+
if (!mathNode) return null;
|
|
1045
|
+
|
|
1046
|
+
state.tr.replaceWith(range.from, range.to, mathNode).scrollIntoView();
|
|
1047
|
+
},
|
|
1048
|
+
}),
|
|
1049
|
+
];
|
|
1050
|
+
},
|
|
1051
|
+
|
|
978
1052
|
addAttributes() {
|
|
979
1053
|
return {
|
|
980
1054
|
tagName: { default: "mention-user" },
|
|
@@ -1023,6 +1097,10 @@ export const NotionInlineAtom = Node.create({
|
|
|
1023
1097
|
];
|
|
1024
1098
|
},
|
|
1025
1099
|
|
|
1100
|
+
addNodeView() {
|
|
1101
|
+
return ReactNodeViewRenderer(InlineAtomView);
|
|
1102
|
+
},
|
|
1103
|
+
|
|
1026
1104
|
addStorage() {
|
|
1027
1105
|
return {
|
|
1028
1106
|
markdown: {
|
|
@@ -61,12 +61,39 @@ export interface PreviewDocumentPayload {
|
|
|
61
61
|
loadedContentWasEmpty?: boolean;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
export interface
|
|
65
|
-
|
|
64
|
+
export interface PreviewDocumentSaveDeferred {
|
|
65
|
+
outcome: "deferred";
|
|
66
|
+
reason: "hydration" | "conflict";
|
|
67
|
+
conflictSnapshot?: PreviewDocumentDraftSnapshot;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
export
|
|
69
|
-
|
|
70
|
+
export interface PreviewDocumentSaveAdapter {
|
|
71
|
+
save: (
|
|
72
|
+
documentId: string,
|
|
73
|
+
payload: PreviewDocumentPayload,
|
|
74
|
+
baseline?: PreviewDocumentPayload,
|
|
75
|
+
) => Promise<unknown>;
|
|
76
|
+
onSaved?: (payload: PreviewDocumentPayload) => void;
|
|
77
|
+
onError?: (error: unknown) => void;
|
|
78
|
+
onDraftConflict?: (snapshot: PreviewDocumentDraftSnapshot) => void;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface PreviewDocumentDraftSnapshot {
|
|
82
|
+
lastSaved: PreviewDocumentPayload;
|
|
83
|
+
pending: PreviewDocumentPayload;
|
|
84
|
+
deferredReason: PreviewDocumentSaveDeferred["reason"] | null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The save could not run yet, but the payload is still user-owned and must stay
|
|
89
|
+
* dirty until a later flush can persist it. This is intentionally different
|
|
90
|
+
* from success: callers must never advance or reset the confirmed baseline.
|
|
91
|
+
*/
|
|
92
|
+
export function deferredPreviewDocumentSave(
|
|
93
|
+
reason: PreviewDocumentSaveDeferred["reason"] = "hydration",
|
|
94
|
+
conflictSnapshot?: PreviewDocumentDraftSnapshot,
|
|
95
|
+
): PreviewDocumentSaveDeferred {
|
|
96
|
+
return { outcome: "deferred", reason, conflictSnapshot };
|
|
70
97
|
}
|
|
71
98
|
|
|
72
99
|
export interface PreviewDocumentSaveController {
|
|
@@ -89,6 +116,19 @@ export interface PreviewDocumentSaveController {
|
|
|
89
116
|
cancel(): void;
|
|
90
117
|
/** Adopt `payload` as the confirmed-saved baseline (no save scheduled). */
|
|
91
118
|
mark(payload: PreviewDocumentPayload): void;
|
|
119
|
+
/**
|
|
120
|
+
* Adopt a fresher server baseline while retaining the user's pending title
|
|
121
|
+
* and content. Used only after an explicit "keep local draft" choice.
|
|
122
|
+
*/
|
|
123
|
+
rebasePending(payload: PreviewDocumentPayload): void;
|
|
124
|
+
/** Replace callbacks captured by an older preview mount. */
|
|
125
|
+
replaceSaveAdapter(adapter: PreviewDocumentSaveAdapter): void;
|
|
126
|
+
/** Serializable dirty state for bounded browser draft storage. */
|
|
127
|
+
draftSnapshot(): PreviewDocumentDraftSnapshot;
|
|
128
|
+
/** Restore a previously persisted dirty draft into a fresh controller. */
|
|
129
|
+
restoreDraft(snapshot: PreviewDocumentDraftSnapshot): void;
|
|
130
|
+
/** Notify whichever preview mount currently owns this controller. */
|
|
131
|
+
notifyDraftConflict(snapshot: PreviewDocumentDraftSnapshot): void;
|
|
92
132
|
/** The payload last CONFIRMED persisted. */
|
|
93
133
|
readonly lastSaved: PreviewDocumentPayload;
|
|
94
134
|
/** The latest payload the user has typed (may differ from lastSaved). */
|
|
@@ -97,6 +137,8 @@ export interface PreviewDocumentSaveController {
|
|
|
97
137
|
readonly hasPendingTimer: boolean;
|
|
98
138
|
/** Whether a save() call is currently outstanding (in flight). */
|
|
99
139
|
readonly isSaving: boolean;
|
|
140
|
+
/** Why the latest attempted save remains dirty, if it was deferred. */
|
|
141
|
+
readonly deferredReason: PreviewDocumentSaveDeferred["reason"] | null;
|
|
100
142
|
/**
|
|
101
143
|
* Whether this controller has confirmed at least one local save since creation.
|
|
102
144
|
* Until the server query echoes that payload, clean local state is newer than
|
|
@@ -109,25 +151,21 @@ function payloadsEqual(a: PreviewDocumentPayload, b: PreviewDocumentPayload) {
|
|
|
109
151
|
return a.title === b.title && a.content === b.content;
|
|
110
152
|
}
|
|
111
153
|
|
|
112
|
-
export function createPreviewDocumentSaveController(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
debounceMs?: number;
|
|
128
|
-
setTimeoutFn?: typeof setTimeout;
|
|
129
|
-
clearTimeoutFn?: typeof clearTimeout;
|
|
130
|
-
}): PreviewDocumentSaveController {
|
|
154
|
+
export function createPreviewDocumentSaveController(
|
|
155
|
+
args: PreviewDocumentSaveAdapter & {
|
|
156
|
+
/**
|
|
157
|
+
* The document id this controller persists to, fixed for its entire life. A
|
|
158
|
+
* controller NEVER changes which document it targets — switching rows acquires
|
|
159
|
+
* a different controller (see previewDocumentSaveRegistry).
|
|
160
|
+
*/
|
|
161
|
+
documentId: string;
|
|
162
|
+
initial: PreviewDocumentPayload;
|
|
163
|
+
/** Persist `payload` to this controller's document. */
|
|
164
|
+
debounceMs?: number;
|
|
165
|
+
setTimeoutFn?: typeof setTimeout;
|
|
166
|
+
clearTimeoutFn?: typeof clearTimeout;
|
|
167
|
+
},
|
|
168
|
+
): PreviewDocumentSaveController {
|
|
131
169
|
const documentId = args.documentId;
|
|
132
170
|
const debounceMs = args.debounceMs ?? 450;
|
|
133
171
|
const setTimeoutFn = args.setTimeoutFn ?? setTimeout;
|
|
@@ -137,6 +175,13 @@ export function createPreviewDocumentSaveController(args: {
|
|
|
137
175
|
let pending: PreviewDocumentPayload = { ...args.initial };
|
|
138
176
|
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
139
177
|
let hasSavedLocally = false;
|
|
178
|
+
let deferredReason: PreviewDocumentSaveDeferred["reason"] | null = null;
|
|
179
|
+
let saveAdapter: PreviewDocumentSaveAdapter = {
|
|
180
|
+
save: args.save,
|
|
181
|
+
onSaved: args.onSaved,
|
|
182
|
+
onError: args.onError,
|
|
183
|
+
onDraftConflict: args.onDraftConflict,
|
|
184
|
+
};
|
|
140
185
|
|
|
141
186
|
// The single in-flight save, or null when idle. A debounced edit made while
|
|
142
187
|
// this is set does NOT start a new save; it updates `pending` and a trailing
|
|
@@ -161,29 +206,42 @@ export function createPreviewDocumentSaveController(args: {
|
|
|
161
206
|
if (payloadsEqual(pending, lastSaved)) return; // nothing dirty.
|
|
162
207
|
|
|
163
208
|
const attempted = { ...pending };
|
|
164
|
-
const promise = Promise.resolve(
|
|
209
|
+
const promise = Promise.resolve(
|
|
210
|
+
saveAdapter.save(documentId, attempted, { ...lastSaved }),
|
|
211
|
+
)
|
|
165
212
|
.then((result) => {
|
|
166
213
|
if (
|
|
167
214
|
result &&
|
|
168
215
|
typeof result === "object" &&
|
|
169
|
-
"
|
|
170
|
-
result.
|
|
216
|
+
"outcome" in result &&
|
|
217
|
+
result.outcome === "deferred" &&
|
|
218
|
+
"reason" in result &&
|
|
219
|
+
(result.reason === "hydration" || result.reason === "conflict")
|
|
171
220
|
) {
|
|
172
|
-
|
|
221
|
+
// Hydration can begin after a keystroke but before the debounce fires.
|
|
222
|
+
// Keep the attempted payload dirty so the registry can retain it across
|
|
223
|
+
// close/reopen and a later flush can retry it. A deferred save is not a
|
|
224
|
+
// successful save, and user-authored content is never disposable.
|
|
225
|
+
deferredReason = result.reason;
|
|
173
226
|
inFlight = null;
|
|
227
|
+
const deferredResult = result as PreviewDocumentSaveDeferred;
|
|
228
|
+
if (deferredResult.conflictSnapshot) {
|
|
229
|
+
saveAdapter.onDraftConflict?.(deferredResult.conflictSnapshot);
|
|
230
|
+
}
|
|
174
231
|
return;
|
|
175
232
|
}
|
|
176
233
|
lastSaved = attempted;
|
|
177
234
|
hasSavedLocally = true;
|
|
235
|
+
deferredReason = null;
|
|
178
236
|
inFlight = null;
|
|
179
|
-
|
|
237
|
+
saveAdapter.onSaved?.(attempted);
|
|
180
238
|
// A trailing edit may have landed while this save was in flight. Issue
|
|
181
239
|
// exactly one more for the LATEST payload. Bounded: stops once quiescent.
|
|
182
240
|
kick();
|
|
183
241
|
})
|
|
184
242
|
.catch((error) => {
|
|
185
243
|
inFlight = null;
|
|
186
|
-
|
|
244
|
+
saveAdapter.onError?.(error);
|
|
187
245
|
});
|
|
188
246
|
inFlight = promise;
|
|
189
247
|
}
|
|
@@ -201,10 +259,12 @@ export function createPreviewDocumentSaveController(args: {
|
|
|
201
259
|
documentId,
|
|
202
260
|
changeTitle(title: string) {
|
|
203
261
|
pending = { ...pending, title };
|
|
262
|
+
deferredReason = null;
|
|
204
263
|
schedule();
|
|
205
264
|
},
|
|
206
265
|
changeContent(content: string) {
|
|
207
266
|
pending = { ...pending, content };
|
|
267
|
+
deferredReason = null;
|
|
208
268
|
schedule();
|
|
209
269
|
},
|
|
210
270
|
flush() {
|
|
@@ -233,6 +293,38 @@ export function createPreviewDocumentSaveController(args: {
|
|
|
233
293
|
lastSaved = { ...payload };
|
|
234
294
|
pending = { ...payload };
|
|
235
295
|
hasSavedLocally = false;
|
|
296
|
+
deferredReason = null;
|
|
297
|
+
},
|
|
298
|
+
rebasePending(payload: PreviewDocumentPayload) {
|
|
299
|
+
clearTimer();
|
|
300
|
+
lastSaved = { ...payload };
|
|
301
|
+
pending = {
|
|
302
|
+
...pending,
|
|
303
|
+
loadedUpdatedAt: payload.loadedUpdatedAt,
|
|
304
|
+
loadedContentWasEmpty: payload.loadedContentWasEmpty,
|
|
305
|
+
};
|
|
306
|
+
hasSavedLocally = false;
|
|
307
|
+
deferredReason = null;
|
|
308
|
+
},
|
|
309
|
+
replaceSaveAdapter(adapter: PreviewDocumentSaveAdapter) {
|
|
310
|
+
saveAdapter = adapter;
|
|
311
|
+
},
|
|
312
|
+
draftSnapshot() {
|
|
313
|
+
return {
|
|
314
|
+
lastSaved: { ...lastSaved },
|
|
315
|
+
pending: { ...pending },
|
|
316
|
+
deferredReason,
|
|
317
|
+
};
|
|
318
|
+
},
|
|
319
|
+
restoreDraft(snapshot: PreviewDocumentDraftSnapshot) {
|
|
320
|
+
clearTimer();
|
|
321
|
+
lastSaved = { ...snapshot.lastSaved };
|
|
322
|
+
pending = { ...snapshot.pending };
|
|
323
|
+
deferredReason = snapshot.deferredReason;
|
|
324
|
+
hasSavedLocally = false;
|
|
325
|
+
},
|
|
326
|
+
notifyDraftConflict(snapshot: PreviewDocumentDraftSnapshot) {
|
|
327
|
+
saveAdapter.onDraftConflict?.(snapshot);
|
|
236
328
|
},
|
|
237
329
|
get lastSaved() {
|
|
238
330
|
return { ...lastSaved };
|
|
@@ -246,6 +338,9 @@ export function createPreviewDocumentSaveController(args: {
|
|
|
246
338
|
get isSaving() {
|
|
247
339
|
return inFlight !== null;
|
|
248
340
|
},
|
|
341
|
+
get deferredReason() {
|
|
342
|
+
return deferredReason;
|
|
343
|
+
},
|
|
249
344
|
get hasSavedLocally() {
|
|
250
345
|
return hasSavedLocally;
|
|
251
346
|
},
|
|
@@ -67,12 +67,14 @@ function controllerIsDirty(controller: PreviewDocumentSaveController): boolean {
|
|
|
67
67
|
export function acquirePreviewDocumentSaveController(
|
|
68
68
|
documentId: string,
|
|
69
69
|
factory: () => PreviewDocumentSaveController,
|
|
70
|
+
refreshAdapter?: (controller: PreviewDocumentSaveController) => void,
|
|
70
71
|
): PreviewDocumentSaveController {
|
|
71
72
|
let entry = registry.get(documentId);
|
|
72
73
|
if (!entry) {
|
|
73
74
|
entry = { controller: factory(), refCount: 0, evicting: false };
|
|
74
75
|
registry.set(documentId, entry);
|
|
75
76
|
}
|
|
77
|
+
refreshAdapter?.(entry.controller);
|
|
76
78
|
entry.refCount += 1;
|
|
77
79
|
// A reopen before a pending eviction settled: keep the instance alive.
|
|
78
80
|
entry.evicting = false;
|
|
@@ -364,6 +364,21 @@
|
|
|
364
364
|
line-height: 1.45;
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
+
.notion-editor h5 {
|
|
368
|
+
font-size: 1em;
|
|
369
|
+
font-weight: 600;
|
|
370
|
+
margin: 0.8em 0 0.15em;
|
|
371
|
+
line-height: 1.5;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.notion-editor h6 {
|
|
375
|
+
font-size: 0.95em;
|
|
376
|
+
font-weight: 600;
|
|
377
|
+
margin: 0.75em 0 0.15em;
|
|
378
|
+
line-height: 1.5;
|
|
379
|
+
color: hsl(var(--muted-foreground));
|
|
380
|
+
}
|
|
381
|
+
|
|
367
382
|
/* Paragraphs */
|
|
368
383
|
.notion-editor p {
|
|
369
384
|
margin: 0.5em 0;
|
|
@@ -408,7 +423,9 @@
|
|
|
408
423
|
.notion-editor h1.is-empty::before,
|
|
409
424
|
.notion-editor h2.is-empty::before,
|
|
410
425
|
.notion-editor h3.is-empty::before,
|
|
411
|
-
.notion-editor h4.is-empty::before
|
|
426
|
+
.notion-editor h4.is-empty::before,
|
|
427
|
+
.notion-editor h5.is-empty::before,
|
|
428
|
+
.notion-editor h6.is-empty::before {
|
|
412
429
|
content: attr(data-placeholder);
|
|
413
430
|
float: left;
|
|
414
431
|
color: hsl(var(--muted-foreground));
|
|
@@ -1201,6 +1218,59 @@ div[data-notion-column] > :last-child {
|
|
|
1201
1218
|
white-space: nowrap;
|
|
1202
1219
|
}
|
|
1203
1220
|
|
|
1221
|
+
.content-inline-equation {
|
|
1222
|
+
display: inline-block;
|
|
1223
|
+
max-width: 100%;
|
|
1224
|
+
margin: 0 0.08em;
|
|
1225
|
+
vertical-align: -0.08em;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
.content-equation {
|
|
1229
|
+
display: block;
|
|
1230
|
+
max-width: 100%;
|
|
1231
|
+
margin: 1em 0;
|
|
1232
|
+
overflow-x: auto;
|
|
1233
|
+
padding: 0.25rem 0;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
.content-math {
|
|
1237
|
+
color: inherit;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
.content-math--inline {
|
|
1241
|
+
display: inline-block;
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
.content-math--block {
|
|
1245
|
+
display: block;
|
|
1246
|
+
min-width: max-content;
|
|
1247
|
+
text-align: center;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
.content-math-error {
|
|
1251
|
+
border: 1px solid hsl(var(--destructive) / 0.3);
|
|
1252
|
+
border-radius: 0.375rem;
|
|
1253
|
+
background: hsl(var(--destructive) / 0.06);
|
|
1254
|
+
color: hsl(var(--foreground));
|
|
1255
|
+
font-family:
|
|
1256
|
+
"JetBrains Mono Variable", ui-monospace, SFMono-Regular, Menlo, Consolas,
|
|
1257
|
+
monospace;
|
|
1258
|
+
white-space: pre-wrap;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
.content-math-error--inline {
|
|
1262
|
+
padding: 0.05rem 0.25rem;
|
|
1263
|
+
font-size: 0.9em;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
.content-math-error--block {
|
|
1267
|
+
display: block;
|
|
1268
|
+
width: 100%;
|
|
1269
|
+
padding: 0.75rem 0.9rem;
|
|
1270
|
+
overflow-wrap: anywhere;
|
|
1271
|
+
text-align: left;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1204
1274
|
.notion-editor span[data-notion-span="true"][underline="true"] {
|
|
1205
1275
|
text-decoration: underline;
|
|
1206
1276
|
text-underline-offset: 3px;
|
|
@@ -4,6 +4,8 @@ import type {
|
|
|
4
4
|
AddDatabaseItemRequest,
|
|
5
5
|
AttachContentDatabaseSourceRequest,
|
|
6
6
|
BuilderCmsModelsResponse,
|
|
7
|
+
CancelPreparedBuilderSourceUpdateRequest,
|
|
8
|
+
CancelPreparedBuilderSourceUpdateResponse,
|
|
7
9
|
ChangeContentDatabaseSourceRoleRequest,
|
|
8
10
|
ContentDatabaseResponse,
|
|
9
11
|
ContentDatabasePersonalViewResponse,
|
|
@@ -25,6 +27,7 @@ import type {
|
|
|
25
27
|
ExecuteBuilderSourceExecutionRequest,
|
|
26
28
|
MoveDatabaseItemRequest,
|
|
27
29
|
PrepareBuilderSourceExecutionRequest,
|
|
30
|
+
PreviewBuilderSourceReviewResponse,
|
|
28
31
|
PrepareBuilderSourceReviewRequest,
|
|
29
32
|
PrepareBuilderSourceReviewResponse,
|
|
30
33
|
ProcessBuilderBodyHydrationRequest,
|
|
@@ -815,6 +818,27 @@ export function useAddContentDatabaseSourceFieldProperty(documentId: string) {
|
|
|
815
818
|
});
|
|
816
819
|
}
|
|
817
820
|
|
|
821
|
+
export function useMaterializeBuilderRequiredFields(documentId: string) {
|
|
822
|
+
const queryClient = useQueryClient();
|
|
823
|
+
return useActionMutation<
|
|
824
|
+
ContentDatabaseResponse,
|
|
825
|
+
{ documentId: string; sourceId: string }
|
|
826
|
+
>("materialize-builder-required-fields", {
|
|
827
|
+
onSuccess: (data) => {
|
|
828
|
+
writeContentDatabaseResponseToCache(queryClient, documentId, data);
|
|
829
|
+
queryClient.invalidateQueries({
|
|
830
|
+
queryKey: contentDatabaseQueryKey(documentId),
|
|
831
|
+
});
|
|
832
|
+
queryClient.invalidateQueries({
|
|
833
|
+
queryKey: ["action", "get-content-database-source", { documentId }],
|
|
834
|
+
});
|
|
835
|
+
queryClient.invalidateQueries({
|
|
836
|
+
queryKey: ["action", "list-document-properties", { documentId }],
|
|
837
|
+
});
|
|
838
|
+
},
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
|
|
818
842
|
export function useBuilderCmsModels(enabled: boolean) {
|
|
819
843
|
return useActionQuery<BuilderCmsModelsResponse>(
|
|
820
844
|
"list-builder-cms-models",
|
|
@@ -1014,6 +1038,23 @@ export function usePrepareBuilderSourceExecution(documentId: string) {
|
|
|
1014
1038
|
});
|
|
1015
1039
|
}
|
|
1016
1040
|
|
|
1041
|
+
export function useCancelPreparedBuilderSourceUpdate(documentId: string) {
|
|
1042
|
+
const queryClient = useQueryClient();
|
|
1043
|
+
return useActionMutation<
|
|
1044
|
+
CancelPreparedBuilderSourceUpdateResponse,
|
|
1045
|
+
CancelPreparedBuilderSourceUpdateRequest
|
|
1046
|
+
>("cancel-prepared-builder-source-update", {
|
|
1047
|
+
onSuccess: () => {
|
|
1048
|
+
queryClient.invalidateQueries({
|
|
1049
|
+
queryKey: contentDatabaseQueryKey(documentId),
|
|
1050
|
+
});
|
|
1051
|
+
queryClient.invalidateQueries({
|
|
1052
|
+
queryKey: ["action", "get-content-database-source", { documentId }],
|
|
1053
|
+
});
|
|
1054
|
+
},
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1017
1058
|
export function useValidateBuilderSourceExecution(documentId: string) {
|
|
1018
1059
|
const queryClient = useQueryClient();
|
|
1019
1060
|
return useActionMutation<
|
|
@@ -1099,6 +1140,33 @@ export function usePrepareBuilderSourceReview(documentId: string) {
|
|
|
1099
1140
|
});
|
|
1100
1141
|
}
|
|
1101
1142
|
|
|
1143
|
+
export function usePreviewBuilderSourceReview(args: {
|
|
1144
|
+
documentId: string;
|
|
1145
|
+
sourceId: string | null;
|
|
1146
|
+
scope: "selected" | "all";
|
|
1147
|
+
documentIds?: string[];
|
|
1148
|
+
enabled: boolean;
|
|
1149
|
+
}) {
|
|
1150
|
+
return useActionQuery<PreviewBuilderSourceReviewResponse>(
|
|
1151
|
+
"preview-builder-source-review",
|
|
1152
|
+
args.enabled && args.sourceId
|
|
1153
|
+
? {
|
|
1154
|
+
documentId: args.documentId,
|
|
1155
|
+
sourceId: args.sourceId,
|
|
1156
|
+
scope: args.scope,
|
|
1157
|
+
documentIds: args.documentIds,
|
|
1158
|
+
}
|
|
1159
|
+
: undefined,
|
|
1160
|
+
{
|
|
1161
|
+
enabled: args.enabled && !!args.sourceId,
|
|
1162
|
+
retry: false,
|
|
1163
|
+
staleTime: 0,
|
|
1164
|
+
gcTime: 0,
|
|
1165
|
+
refetchOnWindowFocus: false,
|
|
1166
|
+
},
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1102
1170
|
export function useStageBuilderSourceBulkUpdate(documentId: string) {
|
|
1103
1171
|
const queryClient = useQueryClient();
|
|
1104
1172
|
return useActionMutation<
|
|
@@ -92,13 +92,15 @@ export function seedDatabaseItemDocumentCaches(
|
|
|
92
92
|
// Seed only cold caches. Overwriting an existing entry would bump its
|
|
93
93
|
// freshness with possibly older table-snapshot data (a background database
|
|
94
94
|
// refetch can lag a just-saved document edit) and suppress the correcting
|
|
95
|
-
// refetch for the whole staleTime window.
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
// an
|
|
95
|
+
// refetch for the whole staleTime window. Source-backed rows are never seeded:
|
|
96
|
+
// list snapshots are not authoritative enough to unlock the body editor, even
|
|
97
|
+
// when they happen to contain non-empty content. The dedicated get-document
|
|
98
|
+
// response owns that decision and prevents an edit from racing hydration.
|
|
99
99
|
if (
|
|
100
100
|
!databaseItemBodyHydrationIsPending(item) &&
|
|
101
101
|
!sourceBackedEmptyBody &&
|
|
102
|
+
!item.bodyHydration &&
|
|
103
|
+
!item.document.databaseMembership?.sourceId &&
|
|
102
104
|
queryClient.getQueryData(documentQueryKey(item.document.id)) === undefined
|
|
103
105
|
) {
|
|
104
106
|
queryClient.setQueryData<Document>(documentQueryKey(item.document.id), {
|
|
@@ -139,6 +141,53 @@ export function useDocument(id: string | null) {
|
|
|
139
141
|
});
|
|
140
142
|
}
|
|
141
143
|
|
|
144
|
+
export interface PreviewDocumentDraftRecord {
|
|
145
|
+
documentId: string;
|
|
146
|
+
title: string;
|
|
147
|
+
content: string;
|
|
148
|
+
baseDocumentUpdatedAt: string | null;
|
|
149
|
+
loadedContentWasEmpty: number;
|
|
150
|
+
deferredReason: string | null;
|
|
151
|
+
version: number;
|
|
152
|
+
updatedAt: string;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function usePreviewDocumentDraft(documentId: string | null) {
|
|
156
|
+
return useActionQuery<{ draft: PreviewDocumentDraftRecord | null }>(
|
|
157
|
+
"get-preview-document-draft",
|
|
158
|
+
documentId ? { documentId } : undefined,
|
|
159
|
+
{ enabled: !!documentId, retry: false },
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function useUpdatePreviewDocumentDraft() {
|
|
164
|
+
return useActionMutation<
|
|
165
|
+
{
|
|
166
|
+
status: "saved" | "deleted" | "conflict";
|
|
167
|
+
draft: PreviewDocumentDraftRecord | null;
|
|
168
|
+
},
|
|
169
|
+
| {
|
|
170
|
+
operation: "upsert";
|
|
171
|
+
documentId: string;
|
|
172
|
+
expectedVersion: number | null;
|
|
173
|
+
draft: {
|
|
174
|
+
title: string;
|
|
175
|
+
content: string;
|
|
176
|
+
baseDocumentUpdatedAt: string | null;
|
|
177
|
+
loadedContentWasEmpty: boolean;
|
|
178
|
+
deferredReason: "hydration" | "conflict" | null;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
| {
|
|
182
|
+
operation: "delete";
|
|
183
|
+
documentId: string;
|
|
184
|
+
expectedVersion: number;
|
|
185
|
+
expectedTitle: string;
|
|
186
|
+
expectedContent: string;
|
|
187
|
+
}
|
|
188
|
+
>("update-preview-document-draft");
|
|
189
|
+
}
|
|
190
|
+
|
|
142
191
|
export function useCreateDocument() {
|
|
143
192
|
return useActionMutation<Document, DocumentCreateRequest>("create-document");
|
|
144
193
|
}
|