@templatical/core 0.48.0 → 0.50.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.
- package/README.md +3 -1
- package/dist/cloud/index.d.ts +3 -151
- package/dist/cloud/index.js +2 -907
- package/dist/cloud/index.js.map +1 -1
- package/dist/index.d.ts +286 -7
- package/dist/index.js +1152 -18
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/editor-Bl4WsPU3.d.ts +0 -105
package/dist/cloud/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SdkError } from "@templatical/types";
|
|
2
|
-
import { computed,
|
|
2
|
+
import { computed, ref, watch } from "vue";
|
|
3
3
|
//#region src/cloud/auth.ts
|
|
4
4
|
/**
|
|
5
5
|
* Whether a token-refresh failure is worth interrupting the user over.
|
|
@@ -178,7 +178,6 @@ function buildUrl(template, params) {
|
|
|
178
178
|
}
|
|
179
179
|
const BASE = "/api/v1/projects/{project}/tenants/{tenant}";
|
|
180
180
|
const TEMPLATE = `${BASE}/templates/{template}`;
|
|
181
|
-
const AI = `${TEMPLATE}/ai`;
|
|
182
181
|
const MEDIA = `${BASE}/media`;
|
|
183
182
|
const FOLDERS = `${MEDIA}/folders`;
|
|
184
183
|
const MODULES = `${BASE}/saved-modules`;
|
|
@@ -202,13 +201,6 @@ const API_ROUTES = {
|
|
|
202
201
|
"comments.update": `${TEMPLATE}/comments/{comment}`,
|
|
203
202
|
"comments.destroy": `${TEMPLATE}/comments/{comment}`,
|
|
204
203
|
"comments.resolve": `${TEMPLATE}/comments/{comment}/resolve`,
|
|
205
|
-
"ai.generate": `${AI}/generate`,
|
|
206
|
-
"ai.conversationMessages": `${AI}/conversation-messages`,
|
|
207
|
-
"ai.suggestions": `${AI}/suggestions`,
|
|
208
|
-
"ai.rewriteText": `${AI}/rewrite-text`,
|
|
209
|
-
"ai.score": `${AI}/score`,
|
|
210
|
-
"ai.fixFinding": `${AI}/fix-finding`,
|
|
211
|
-
"ai.generateFromDesign": `${AI}/generate-from-design`,
|
|
212
204
|
"media.upload": `${MEDIA}/upload`,
|
|
213
205
|
"media.browse": `${MEDIA}/browse`,
|
|
214
206
|
"media.delete": `${MEDIA}/delete`,
|
|
@@ -693,650 +685,6 @@ var WebSocketClient = class {
|
|
|
693
685
|
}
|
|
694
686
|
};
|
|
695
687
|
//#endregion
|
|
696
|
-
//#region src/cloud/mcp-operation-handler.ts
|
|
697
|
-
function handleOperation(editor, payload) {
|
|
698
|
-
const { operation, data } = payload;
|
|
699
|
-
switch (operation) {
|
|
700
|
-
case "addBlock":
|
|
701
|
-
editor.addBlock(data.block, data.sectionId, data.columnIndex, data.index);
|
|
702
|
-
break;
|
|
703
|
-
case "updateBlock":
|
|
704
|
-
editor.updateBlock(data.blockId, data.updates);
|
|
705
|
-
break;
|
|
706
|
-
case "deleteBlock":
|
|
707
|
-
editor.removeBlock(data.blockId);
|
|
708
|
-
break;
|
|
709
|
-
case "moveBlock":
|
|
710
|
-
editor.moveBlock(data.blockId, data.index, data.sectionId, data.columnIndex);
|
|
711
|
-
break;
|
|
712
|
-
case "updateSettings":
|
|
713
|
-
editor.updateSettings(data.updates);
|
|
714
|
-
break;
|
|
715
|
-
case "setContent":
|
|
716
|
-
editor.setContent(data.content);
|
|
717
|
-
break;
|
|
718
|
-
case "updateBlockStyle": editor.updateBlock(data.blockId, { styles: data.styles });
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
//#endregion
|
|
722
|
-
//#region src/cloud/ai-chat.ts
|
|
723
|
-
let messageIdCounter = 0;
|
|
724
|
-
function generateMessageId() {
|
|
725
|
-
return `msg_${Date.now()}_${++messageIdCounter}`;
|
|
726
|
-
}
|
|
727
|
-
function useAiChat(options) {
|
|
728
|
-
const { authManager, getTemplateId, onApply, onError } = options;
|
|
729
|
-
const messages = ref([]);
|
|
730
|
-
const isGenerating = ref(false);
|
|
731
|
-
const isLoadingHistory = ref(false);
|
|
732
|
-
const error = ref(null);
|
|
733
|
-
const failedPrompt = ref(null);
|
|
734
|
-
const conversationId = ref(null);
|
|
735
|
-
const lastApplyMessageId = ref(null);
|
|
736
|
-
const lastPreviousContent = ref(null);
|
|
737
|
-
const lastAppliedContent = ref(null);
|
|
738
|
-
const isLastChangeReverted = ref(false);
|
|
739
|
-
const suggestions = ref([]);
|
|
740
|
-
const isLoadingSuggestions = ref(false);
|
|
741
|
-
function updateMessage(msgId, updates) {
|
|
742
|
-
const idx = messages.value.findIndex((m) => m.id === msgId);
|
|
743
|
-
if (idx === -1) return;
|
|
744
|
-
const updated = {
|
|
745
|
-
...messages.value[idx],
|
|
746
|
-
...updates
|
|
747
|
-
};
|
|
748
|
-
messages.value = [
|
|
749
|
-
...messages.value.slice(0, idx),
|
|
750
|
-
updated,
|
|
751
|
-
...messages.value.slice(idx + 1)
|
|
752
|
-
];
|
|
753
|
-
}
|
|
754
|
-
async function loadConversation() {
|
|
755
|
-
const templateId = getTemplateId();
|
|
756
|
-
if (!templateId) return;
|
|
757
|
-
isLoadingHistory.value = true;
|
|
758
|
-
try {
|
|
759
|
-
const url = buildUrl(API_ROUTES["ai.conversationMessages"], {
|
|
760
|
-
project: authManager.projectId,
|
|
761
|
-
tenant: authManager.tenantSlug,
|
|
762
|
-
template: templateId
|
|
763
|
-
});
|
|
764
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
765
|
-
method: "GET",
|
|
766
|
-
headers: { Accept: "application/json" }
|
|
767
|
-
});
|
|
768
|
-
if (!response.ok) return;
|
|
769
|
-
const data = await response.json();
|
|
770
|
-
if (data.conversationId) conversationId.value = data.conversationId;
|
|
771
|
-
if (Array.isArray(data.data) && data.data.length > 0) messages.value = data.data.map((msg) => ({
|
|
772
|
-
id: msg.id,
|
|
773
|
-
role: msg.role,
|
|
774
|
-
content: msg.content,
|
|
775
|
-
timestamp: new Date(msg.createdAt).getTime()
|
|
776
|
-
}));
|
|
777
|
-
} catch {} finally {
|
|
778
|
-
isLoadingHistory.value = false;
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
async function loadSuggestions(currentContent, mergeTags) {
|
|
782
|
-
const templateId = getTemplateId();
|
|
783
|
-
if (!templateId) return;
|
|
784
|
-
isLoadingSuggestions.value = true;
|
|
785
|
-
try {
|
|
786
|
-
const url = buildUrl(API_ROUTES["ai.suggestions"], {
|
|
787
|
-
project: authManager.projectId,
|
|
788
|
-
tenant: authManager.tenantSlug,
|
|
789
|
-
template: templateId
|
|
790
|
-
});
|
|
791
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
792
|
-
method: "POST",
|
|
793
|
-
headers: {
|
|
794
|
-
"Content-Type": "application/json",
|
|
795
|
-
Accept: "text/event-stream"
|
|
796
|
-
},
|
|
797
|
-
body: JSON.stringify({
|
|
798
|
-
currentContent,
|
|
799
|
-
mergeTags: mergeTags.map((p) => ({
|
|
800
|
-
label: p.label,
|
|
801
|
-
value: p.value
|
|
802
|
-
}))
|
|
803
|
-
})
|
|
804
|
-
});
|
|
805
|
-
if (!response.ok) return;
|
|
806
|
-
const reader = response.body?.getReader();
|
|
807
|
-
if (!reader) return;
|
|
808
|
-
const decoder = new TextDecoder();
|
|
809
|
-
let buffer = "";
|
|
810
|
-
while (true) {
|
|
811
|
-
const { done, value } = await reader.read();
|
|
812
|
-
if (done) break;
|
|
813
|
-
buffer += decoder.decode(value, { stream: true });
|
|
814
|
-
const lines = buffer.split("\n");
|
|
815
|
-
buffer = lines.pop() ?? "";
|
|
816
|
-
for (const line of lines) {
|
|
817
|
-
if (!line.startsWith("data: ")) continue;
|
|
818
|
-
let event;
|
|
819
|
-
try {
|
|
820
|
-
event = JSON.parse(line.slice(6));
|
|
821
|
-
} catch {
|
|
822
|
-
continue;
|
|
823
|
-
}
|
|
824
|
-
if (event.type === "done" && Array.isArray(event.suggestions)) suggestions.value = event.suggestions.slice(0, 3);
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
} catch {} finally {
|
|
828
|
-
isLoadingSuggestions.value = false;
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
async function sendPrompt(prompt, currentContent, mergeTags) {
|
|
832
|
-
const templateId = getTemplateId();
|
|
833
|
-
if (!templateId) throw new Error("Template must be saved before using AI generation");
|
|
834
|
-
isGenerating.value = true;
|
|
835
|
-
error.value = null;
|
|
836
|
-
failedPrompt.value = null;
|
|
837
|
-
suggestions.value = [];
|
|
838
|
-
const userMsgId = generateMessageId();
|
|
839
|
-
messages.value = [...messages.value, {
|
|
840
|
-
id: userMsgId,
|
|
841
|
-
role: "user",
|
|
842
|
-
content: prompt,
|
|
843
|
-
timestamp: Date.now()
|
|
844
|
-
}];
|
|
845
|
-
const assistantMsgId = generateMessageId();
|
|
846
|
-
messages.value = [...messages.value, {
|
|
847
|
-
id: assistantMsgId,
|
|
848
|
-
role: "assistant",
|
|
849
|
-
content: "",
|
|
850
|
-
timestamp: Date.now()
|
|
851
|
-
}];
|
|
852
|
-
try {
|
|
853
|
-
const url = buildUrl(API_ROUTES["ai.generate"], {
|
|
854
|
-
project: authManager.projectId,
|
|
855
|
-
tenant: authManager.tenantSlug,
|
|
856
|
-
template: templateId
|
|
857
|
-
});
|
|
858
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
859
|
-
method: "POST",
|
|
860
|
-
headers: {
|
|
861
|
-
"Content-Type": "application/json",
|
|
862
|
-
Accept: "text/event-stream"
|
|
863
|
-
},
|
|
864
|
-
body: JSON.stringify({
|
|
865
|
-
prompt,
|
|
866
|
-
currentContent,
|
|
867
|
-
mergeTags: mergeTags.map((p) => ({
|
|
868
|
-
label: p.label,
|
|
869
|
-
value: p.value
|
|
870
|
-
})),
|
|
871
|
-
conversationId: conversationId.value
|
|
872
|
-
})
|
|
873
|
-
});
|
|
874
|
-
if (!response.ok) {
|
|
875
|
-
const errorData = await response.json().catch(() => null);
|
|
876
|
-
if (response.status === 403) throw new Error("aiGenerationNotAvailable");
|
|
877
|
-
throw new Error(errorData?.message || "Failed to generate template");
|
|
878
|
-
}
|
|
879
|
-
const reader = response.body?.getReader();
|
|
880
|
-
if (!reader) throw new Error("Failed to read stream");
|
|
881
|
-
const decoder = new TextDecoder();
|
|
882
|
-
let buffer = "";
|
|
883
|
-
let result = null;
|
|
884
|
-
try {
|
|
885
|
-
while (true) {
|
|
886
|
-
const { done, value } = await reader.read();
|
|
887
|
-
if (done) break;
|
|
888
|
-
buffer += decoder.decode(value, { stream: true });
|
|
889
|
-
const lines = buffer.split("\n");
|
|
890
|
-
buffer = lines.pop() ?? "";
|
|
891
|
-
for (const line of lines) {
|
|
892
|
-
if (!line.startsWith("data: ")) continue;
|
|
893
|
-
const jsonStr = line.slice(6);
|
|
894
|
-
let event;
|
|
895
|
-
try {
|
|
896
|
-
event = JSON.parse(jsonStr);
|
|
897
|
-
} catch {
|
|
898
|
-
continue;
|
|
899
|
-
}
|
|
900
|
-
if (event.type === "text") updateMessage(assistantMsgId, { content: (messages.value.find((m) => m.id === assistantMsgId)?.content ?? "") + event.text });
|
|
901
|
-
else if (event.type === "error") throw new Error(event.message || "Failed to generate template");
|
|
902
|
-
else if (event.type === "done") {
|
|
903
|
-
if (event.conversationId) conversationId.value = event.conversationId;
|
|
904
|
-
updateMessage(assistantMsgId, { content: event.text });
|
|
905
|
-
result = event.content ?? null;
|
|
906
|
-
if (result) {
|
|
907
|
-
lastPreviousContent.value = currentContent;
|
|
908
|
-
lastAppliedContent.value = result;
|
|
909
|
-
lastApplyMessageId.value = assistantMsgId;
|
|
910
|
-
isLastChangeReverted.value = false;
|
|
911
|
-
onApply?.(result);
|
|
912
|
-
} else error.value = "ai_apply_failed";
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
} finally {
|
|
917
|
-
reader.cancel().catch(() => {});
|
|
918
|
-
}
|
|
919
|
-
return result;
|
|
920
|
-
} catch (err) {
|
|
921
|
-
const wrappedError = err instanceof Error ? err : new Error("Failed to generate template", { cause: err });
|
|
922
|
-
error.value = wrappedError.message;
|
|
923
|
-
failedPrompt.value = prompt;
|
|
924
|
-
onError?.(wrappedError);
|
|
925
|
-
messages.value = messages.value.filter((m) => m.id !== userMsgId && m.id !== assistantMsgId);
|
|
926
|
-
return null;
|
|
927
|
-
} finally {
|
|
928
|
-
isGenerating.value = false;
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
function toggleLastRevert() {
|
|
932
|
-
if (isLastChangeReverted.value) {
|
|
933
|
-
if (lastAppliedContent.value) onApply?.(lastAppliedContent.value);
|
|
934
|
-
isLastChangeReverted.value = false;
|
|
935
|
-
} else {
|
|
936
|
-
if (lastPreviousContent.value) onApply?.(lastPreviousContent.value);
|
|
937
|
-
isLastChangeReverted.value = true;
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
function clearChat() {
|
|
941
|
-
messages.value = [];
|
|
942
|
-
conversationId.value = null;
|
|
943
|
-
error.value = null;
|
|
944
|
-
lastApplyMessageId.value = null;
|
|
945
|
-
lastPreviousContent.value = null;
|
|
946
|
-
lastAppliedContent.value = null;
|
|
947
|
-
isLastChangeReverted.value = false;
|
|
948
|
-
}
|
|
949
|
-
return {
|
|
950
|
-
messages,
|
|
951
|
-
isGenerating,
|
|
952
|
-
isLoadingHistory,
|
|
953
|
-
isLastChangeReverted,
|
|
954
|
-
lastApplyMessageId,
|
|
955
|
-
error,
|
|
956
|
-
failedPrompt,
|
|
957
|
-
suggestions,
|
|
958
|
-
isLoadingSuggestions,
|
|
959
|
-
sendPrompt,
|
|
960
|
-
toggleLastRevert,
|
|
961
|
-
loadConversation,
|
|
962
|
-
loadSuggestions,
|
|
963
|
-
clearChat
|
|
964
|
-
};
|
|
965
|
-
}
|
|
966
|
-
//#endregion
|
|
967
|
-
//#region src/cloud/ai-rewrite.ts
|
|
968
|
-
function useAiRewrite(options) {
|
|
969
|
-
const { authManager, getTemplateId } = options;
|
|
970
|
-
const isRewriting = ref(false);
|
|
971
|
-
const streamingText = ref("");
|
|
972
|
-
const previousContent = ref(null);
|
|
973
|
-
const rewrittenContent = ref(null);
|
|
974
|
-
const isReverted = ref(false);
|
|
975
|
-
const error = ref(null);
|
|
976
|
-
async function rewrite(content, instruction, mergeTags) {
|
|
977
|
-
const templateId = getTemplateId();
|
|
978
|
-
if (!templateId) return null;
|
|
979
|
-
isRewriting.value = true;
|
|
980
|
-
streamingText.value = "";
|
|
981
|
-
error.value = null;
|
|
982
|
-
try {
|
|
983
|
-
const url = buildUrl(API_ROUTES["ai.rewriteText"], {
|
|
984
|
-
project: authManager.projectId,
|
|
985
|
-
tenant: authManager.tenantSlug,
|
|
986
|
-
template: templateId
|
|
987
|
-
});
|
|
988
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
989
|
-
method: "POST",
|
|
990
|
-
headers: {
|
|
991
|
-
"Content-Type": "application/json",
|
|
992
|
-
Accept: "text/event-stream"
|
|
993
|
-
},
|
|
994
|
-
body: JSON.stringify({
|
|
995
|
-
content,
|
|
996
|
-
instruction,
|
|
997
|
-
mergeTags: mergeTags.map((p) => ({
|
|
998
|
-
label: p.label,
|
|
999
|
-
value: p.value
|
|
1000
|
-
}))
|
|
1001
|
-
})
|
|
1002
|
-
});
|
|
1003
|
-
if (!response.ok) {
|
|
1004
|
-
if (response.status === 403) throw new Error("aiGenerationNotAvailable");
|
|
1005
|
-
const errorData = await response.json().catch(() => null);
|
|
1006
|
-
throw new Error(errorData?.message || "Failed to rewrite text");
|
|
1007
|
-
}
|
|
1008
|
-
const reader = response.body?.getReader();
|
|
1009
|
-
if (!reader) throw new Error("Failed to read stream");
|
|
1010
|
-
const decoder = new TextDecoder();
|
|
1011
|
-
let buffer = "";
|
|
1012
|
-
let result = null;
|
|
1013
|
-
while (true) {
|
|
1014
|
-
const { done, value } = await reader.read();
|
|
1015
|
-
if (done) break;
|
|
1016
|
-
buffer += decoder.decode(value, { stream: true });
|
|
1017
|
-
const lines = buffer.split("\n");
|
|
1018
|
-
buffer = lines.pop() ?? "";
|
|
1019
|
-
for (const line of lines) {
|
|
1020
|
-
if (!line.startsWith("data: ")) continue;
|
|
1021
|
-
let event;
|
|
1022
|
-
try {
|
|
1023
|
-
event = JSON.parse(line.slice(6));
|
|
1024
|
-
} catch {
|
|
1025
|
-
continue;
|
|
1026
|
-
}
|
|
1027
|
-
if (event.type === "text") streamingText.value += event.text;
|
|
1028
|
-
else if (event.type === "error") throw new Error(event.message || "Failed to rewrite text");
|
|
1029
|
-
else if (event.type === "done") {
|
|
1030
|
-
result = event.content ?? null;
|
|
1031
|
-
if (result) {
|
|
1032
|
-
previousContent.value = content;
|
|
1033
|
-
rewrittenContent.value = result;
|
|
1034
|
-
isReverted.value = false;
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
return result;
|
|
1040
|
-
} catch (err) {
|
|
1041
|
-
error.value = err instanceof Error ? err.message : "Failed to rewrite text";
|
|
1042
|
-
return null;
|
|
1043
|
-
} finally {
|
|
1044
|
-
isRewriting.value = false;
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
function undo() {
|
|
1048
|
-
if (!previousContent.value) return null;
|
|
1049
|
-
isReverted.value = true;
|
|
1050
|
-
return previousContent.value;
|
|
1051
|
-
}
|
|
1052
|
-
function redo() {
|
|
1053
|
-
if (!rewrittenContent.value) return null;
|
|
1054
|
-
isReverted.value = false;
|
|
1055
|
-
return rewrittenContent.value;
|
|
1056
|
-
}
|
|
1057
|
-
function reset() {
|
|
1058
|
-
isRewriting.value = false;
|
|
1059
|
-
streamingText.value = "";
|
|
1060
|
-
previousContent.value = null;
|
|
1061
|
-
rewrittenContent.value = null;
|
|
1062
|
-
isReverted.value = false;
|
|
1063
|
-
error.value = null;
|
|
1064
|
-
}
|
|
1065
|
-
return {
|
|
1066
|
-
isRewriting,
|
|
1067
|
-
streamingText,
|
|
1068
|
-
previousContent,
|
|
1069
|
-
rewrittenContent,
|
|
1070
|
-
isReverted,
|
|
1071
|
-
error,
|
|
1072
|
-
rewrite,
|
|
1073
|
-
undo,
|
|
1074
|
-
redo,
|
|
1075
|
-
reset
|
|
1076
|
-
};
|
|
1077
|
-
}
|
|
1078
|
-
//#endregion
|
|
1079
|
-
//#region src/cloud/ai-config.ts
|
|
1080
|
-
function useAiConfig(config) {
|
|
1081
|
-
function isFeatureEnabled(feature) {
|
|
1082
|
-
if (config === false) return false;
|
|
1083
|
-
return config?.[feature] !== false;
|
|
1084
|
-
}
|
|
1085
|
-
return {
|
|
1086
|
-
isFeatureEnabled,
|
|
1087
|
-
hasAnyMenuFeature: computed(() => isFeatureEnabled("chat") || isFeatureEnabled("scoring") || isFeatureEnabled("designToTemplate"))
|
|
1088
|
-
};
|
|
1089
|
-
}
|
|
1090
|
-
//#endregion
|
|
1091
|
-
//#region src/cloud/template-scoring.ts
|
|
1092
|
-
function useTemplateScoring(options) {
|
|
1093
|
-
const { authManager, getTemplateId } = options;
|
|
1094
|
-
const isScoring = ref(false);
|
|
1095
|
-
const scoringResult = ref(null);
|
|
1096
|
-
const error = ref(null);
|
|
1097
|
-
const fixingFindingId = ref(null);
|
|
1098
|
-
const fixStreamingText = ref("");
|
|
1099
|
-
const fixError = ref(null);
|
|
1100
|
-
async function score(content, mergeTags) {
|
|
1101
|
-
const templateId = getTemplateId();
|
|
1102
|
-
if (!templateId) return null;
|
|
1103
|
-
isScoring.value = true;
|
|
1104
|
-
error.value = null;
|
|
1105
|
-
scoringResult.value = null;
|
|
1106
|
-
try {
|
|
1107
|
-
const url = buildUrl(API_ROUTES["ai.score"], {
|
|
1108
|
-
project: authManager.projectId,
|
|
1109
|
-
tenant: authManager.tenantSlug,
|
|
1110
|
-
template: templateId
|
|
1111
|
-
});
|
|
1112
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
1113
|
-
method: "POST",
|
|
1114
|
-
headers: {
|
|
1115
|
-
"Content-Type": "application/json",
|
|
1116
|
-
Accept: "text/event-stream"
|
|
1117
|
-
},
|
|
1118
|
-
body: JSON.stringify({
|
|
1119
|
-
currentContent: content,
|
|
1120
|
-
mergeTags: mergeTags.map((p) => ({
|
|
1121
|
-
label: p.label,
|
|
1122
|
-
value: p.value
|
|
1123
|
-
}))
|
|
1124
|
-
})
|
|
1125
|
-
});
|
|
1126
|
-
if (!response.ok) {
|
|
1127
|
-
if (response.status === 403) throw new Error("aiGenerationNotAvailable");
|
|
1128
|
-
const errorData = await response.json().catch(() => null);
|
|
1129
|
-
throw new Error(errorData?.message || "Failed to score template");
|
|
1130
|
-
}
|
|
1131
|
-
const reader = response.body?.getReader();
|
|
1132
|
-
if (!reader) throw new Error("Failed to read stream");
|
|
1133
|
-
const decoder = new TextDecoder();
|
|
1134
|
-
let buffer = "";
|
|
1135
|
-
let result = null;
|
|
1136
|
-
while (true) {
|
|
1137
|
-
const { done, value } = await reader.read();
|
|
1138
|
-
if (done) break;
|
|
1139
|
-
buffer += decoder.decode(value, { stream: true });
|
|
1140
|
-
const lines = buffer.split("\n");
|
|
1141
|
-
buffer = lines.pop() ?? "";
|
|
1142
|
-
for (const line of lines) {
|
|
1143
|
-
if (!line.startsWith("data: ")) continue;
|
|
1144
|
-
let event;
|
|
1145
|
-
try {
|
|
1146
|
-
event = JSON.parse(line.slice(6));
|
|
1147
|
-
} catch {
|
|
1148
|
-
continue;
|
|
1149
|
-
}
|
|
1150
|
-
if (event.type === "error") throw new Error(event.message || "Failed to score template");
|
|
1151
|
-
if (event.type === "done") result = event.result ?? null;
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
if (result) for (const [category, categoryData] of Object.entries(result.categories)) for (const finding of categoryData.findings) finding.category = category;
|
|
1155
|
-
scoringResult.value = result;
|
|
1156
|
-
return result;
|
|
1157
|
-
} catch (err) {
|
|
1158
|
-
error.value = err instanceof Error ? err.message : "Failed to score template";
|
|
1159
|
-
return null;
|
|
1160
|
-
} finally {
|
|
1161
|
-
isScoring.value = false;
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
async function fixFinding(blockContent, finding, mergeTags) {
|
|
1165
|
-
const templateId = getTemplateId();
|
|
1166
|
-
if (!templateId) return null;
|
|
1167
|
-
fixingFindingId.value = finding.id;
|
|
1168
|
-
fixStreamingText.value = "";
|
|
1169
|
-
fixError.value = null;
|
|
1170
|
-
try {
|
|
1171
|
-
const url = buildUrl(API_ROUTES["ai.fixFinding"], {
|
|
1172
|
-
project: authManager.projectId,
|
|
1173
|
-
tenant: authManager.tenantSlug,
|
|
1174
|
-
template: templateId
|
|
1175
|
-
});
|
|
1176
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
1177
|
-
method: "POST",
|
|
1178
|
-
headers: {
|
|
1179
|
-
"Content-Type": "application/json",
|
|
1180
|
-
Accept: "text/event-stream"
|
|
1181
|
-
},
|
|
1182
|
-
body: JSON.stringify({
|
|
1183
|
-
content: blockContent,
|
|
1184
|
-
finding: {
|
|
1185
|
-
id: finding.id,
|
|
1186
|
-
message: finding.message,
|
|
1187
|
-
suggestion: finding.suggestion,
|
|
1188
|
-
category: finding.category
|
|
1189
|
-
},
|
|
1190
|
-
mergeTags: mergeTags.map((p) => ({
|
|
1191
|
-
label: p.label,
|
|
1192
|
-
value: p.value
|
|
1193
|
-
}))
|
|
1194
|
-
})
|
|
1195
|
-
});
|
|
1196
|
-
if (!response.ok) {
|
|
1197
|
-
if (response.status === 403) throw new Error("aiGenerationNotAvailable");
|
|
1198
|
-
const errorData = await response.json().catch(() => null);
|
|
1199
|
-
throw new Error(errorData?.message || "Failed to fix finding");
|
|
1200
|
-
}
|
|
1201
|
-
const reader = response.body?.getReader();
|
|
1202
|
-
if (!reader) throw new Error("Failed to read stream");
|
|
1203
|
-
const decoder = new TextDecoder();
|
|
1204
|
-
let buffer = "";
|
|
1205
|
-
let result = null;
|
|
1206
|
-
while (true) {
|
|
1207
|
-
const { done, value } = await reader.read();
|
|
1208
|
-
if (done) break;
|
|
1209
|
-
buffer += decoder.decode(value, { stream: true });
|
|
1210
|
-
const lines = buffer.split("\n");
|
|
1211
|
-
buffer = lines.pop() ?? "";
|
|
1212
|
-
for (const line of lines) {
|
|
1213
|
-
if (!line.startsWith("data: ")) continue;
|
|
1214
|
-
let event;
|
|
1215
|
-
try {
|
|
1216
|
-
event = JSON.parse(line.slice(6));
|
|
1217
|
-
} catch {
|
|
1218
|
-
continue;
|
|
1219
|
-
}
|
|
1220
|
-
if (event.type === "text") fixStreamingText.value += event.text;
|
|
1221
|
-
else if (event.type === "error") throw new Error(event.message || "Failed to fix finding");
|
|
1222
|
-
else if (event.type === "done") result = event.content ?? null;
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
return result;
|
|
1226
|
-
} catch (err) {
|
|
1227
|
-
fixError.value = err instanceof Error ? err.message : "Failed to fix finding";
|
|
1228
|
-
return null;
|
|
1229
|
-
} finally {
|
|
1230
|
-
fixingFindingId.value = null;
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
function removeFinding(category, findingId) {
|
|
1234
|
-
if (!scoringResult.value) return;
|
|
1235
|
-
const cat = scoringResult.value.categories[category];
|
|
1236
|
-
if (!cat) return;
|
|
1237
|
-
cat.findings = cat.findings.filter((f) => f.id !== findingId);
|
|
1238
|
-
}
|
|
1239
|
-
function reset() {
|
|
1240
|
-
isScoring.value = false;
|
|
1241
|
-
scoringResult.value = null;
|
|
1242
|
-
error.value = null;
|
|
1243
|
-
fixingFindingId.value = null;
|
|
1244
|
-
fixStreamingText.value = "";
|
|
1245
|
-
fixError.value = null;
|
|
1246
|
-
}
|
|
1247
|
-
return {
|
|
1248
|
-
isScoring,
|
|
1249
|
-
scoringResult,
|
|
1250
|
-
error,
|
|
1251
|
-
fixingFindingId,
|
|
1252
|
-
fixStreamingText,
|
|
1253
|
-
fixError,
|
|
1254
|
-
score,
|
|
1255
|
-
fixFinding,
|
|
1256
|
-
removeFinding,
|
|
1257
|
-
reset
|
|
1258
|
-
};
|
|
1259
|
-
}
|
|
1260
|
-
//#endregion
|
|
1261
|
-
//#region src/cloud/design-reference.ts
|
|
1262
|
-
function useDesignReference(options) {
|
|
1263
|
-
const { authManager, getTemplateId, onApply, onError } = options;
|
|
1264
|
-
const isGenerating = ref(false);
|
|
1265
|
-
const error = ref(null);
|
|
1266
|
-
async function generate(input) {
|
|
1267
|
-
const templateId = getTemplateId();
|
|
1268
|
-
if (!templateId) throw new Error("Template must be saved before using design reference");
|
|
1269
|
-
isGenerating.value = true;
|
|
1270
|
-
error.value = null;
|
|
1271
|
-
try {
|
|
1272
|
-
const formData = new FormData();
|
|
1273
|
-
if (input.prompt) formData.append("prompt", input.prompt);
|
|
1274
|
-
if (input.imageUpload) formData.append("image_upload", input.imageUpload);
|
|
1275
|
-
if (input.pdfUpload) formData.append("pdf_upload", input.pdfUpload);
|
|
1276
|
-
const url = buildUrl(API_ROUTES["ai.generateFromDesign"], {
|
|
1277
|
-
project: authManager.projectId,
|
|
1278
|
-
tenant: authManager.tenantSlug,
|
|
1279
|
-
template: templateId
|
|
1280
|
-
});
|
|
1281
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
1282
|
-
method: "POST",
|
|
1283
|
-
headers: { Accept: "text/event-stream" },
|
|
1284
|
-
body: formData
|
|
1285
|
-
});
|
|
1286
|
-
if (!response.ok) {
|
|
1287
|
-
const errorData = await response.json().catch(() => null);
|
|
1288
|
-
if (response.status === 403) throw new Error("aiGenerationNotAvailable");
|
|
1289
|
-
throw new Error(errorData?.message || "Failed to generate template from design");
|
|
1290
|
-
}
|
|
1291
|
-
const reader = response.body?.getReader();
|
|
1292
|
-
if (!reader) throw new Error("Failed to read stream");
|
|
1293
|
-
const decoder = new TextDecoder();
|
|
1294
|
-
let buffer = "";
|
|
1295
|
-
let result = null;
|
|
1296
|
-
while (true) {
|
|
1297
|
-
const { done, value } = await reader.read();
|
|
1298
|
-
if (done) break;
|
|
1299
|
-
buffer += decoder.decode(value, { stream: true });
|
|
1300
|
-
const lines = buffer.split("\n");
|
|
1301
|
-
buffer = lines.pop() ?? "";
|
|
1302
|
-
for (const line of lines) {
|
|
1303
|
-
if (!line.startsWith("data: ")) continue;
|
|
1304
|
-
const jsonStr = line.slice(6);
|
|
1305
|
-
let event;
|
|
1306
|
-
try {
|
|
1307
|
-
event = JSON.parse(jsonStr);
|
|
1308
|
-
} catch {
|
|
1309
|
-
continue;
|
|
1310
|
-
}
|
|
1311
|
-
if (event.type === "error") throw new Error(event.message || "Failed to generate template from design");
|
|
1312
|
-
if (event.type === "done") {
|
|
1313
|
-
result = event.content ?? null;
|
|
1314
|
-
if (result) onApply?.(result);
|
|
1315
|
-
}
|
|
1316
|
-
}
|
|
1317
|
-
}
|
|
1318
|
-
return result;
|
|
1319
|
-
} catch (err) {
|
|
1320
|
-
const wrappedError = err instanceof Error ? err : new Error("Failed to generate template from design", { cause: err });
|
|
1321
|
-
error.value = wrappedError.message;
|
|
1322
|
-
onError?.(wrappedError);
|
|
1323
|
-
return null;
|
|
1324
|
-
} finally {
|
|
1325
|
-
isGenerating.value = false;
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
function reset() {
|
|
1329
|
-
isGenerating.value = false;
|
|
1330
|
-
error.value = null;
|
|
1331
|
-
}
|
|
1332
|
-
return {
|
|
1333
|
-
isGenerating,
|
|
1334
|
-
error,
|
|
1335
|
-
generate,
|
|
1336
|
-
reset
|
|
1337
|
-
};
|
|
1338
|
-
}
|
|
1339
|
-
//#endregion
|
|
1340
688
|
//#region src/cloud/comments-provider.ts
|
|
1341
689
|
/** The Pusher event Cloud's backend fans comment writes out on. */
|
|
1342
690
|
const BROADCAST_EVENT = "comment-broadcast";
|
|
@@ -1461,247 +809,6 @@ function createCloudCommentsProvider(options) {
|
|
|
1461
809
|
};
|
|
1462
810
|
}
|
|
1463
811
|
//#endregion
|
|
1464
|
-
//#region src/cloud/collaboration.ts
|
|
1465
|
-
const COLLAB_EVENTS = [
|
|
1466
|
-
"pusher:member_added",
|
|
1467
|
-
"pusher:member_removed",
|
|
1468
|
-
"client-blockLocked",
|
|
1469
|
-
"client-blockUnlocked",
|
|
1470
|
-
"client-operation",
|
|
1471
|
-
"mcp-operation"
|
|
1472
|
-
];
|
|
1473
|
-
function unbindCollabEvents(channel) {
|
|
1474
|
-
for (const event of COLLAB_EVENTS) channel.unbind(event);
|
|
1475
|
-
}
|
|
1476
|
-
const COLLABORATOR_COLORS = [
|
|
1477
|
-
"#3b82f6",
|
|
1478
|
-
"#ef4444",
|
|
1479
|
-
"#10b981",
|
|
1480
|
-
"#f59e0b",
|
|
1481
|
-
"#8b5cf6",
|
|
1482
|
-
"#ec4899",
|
|
1483
|
-
"#06b6d4",
|
|
1484
|
-
"#f97316",
|
|
1485
|
-
"#6366f1",
|
|
1486
|
-
"#14b8a6"
|
|
1487
|
-
];
|
|
1488
|
-
function useCollaboration(options) {
|
|
1489
|
-
const { authManager, editor, channel } = options;
|
|
1490
|
-
const collaborators = ref([]);
|
|
1491
|
-
const lockedBlocks = ref(/* @__PURE__ */ new Map());
|
|
1492
|
-
let colorIndex = 0;
|
|
1493
|
-
let isProcessingRemoteOperation = false;
|
|
1494
|
-
const myUserId = computed(() => authManager.userConfig?.id ?? "");
|
|
1495
|
-
function assignColor() {
|
|
1496
|
-
const color = COLLABORATOR_COLORS[colorIndex % COLLABORATOR_COLORS.length];
|
|
1497
|
-
colorIndex++;
|
|
1498
|
-
return color;
|
|
1499
|
-
}
|
|
1500
|
-
function addCollaborator(member) {
|
|
1501
|
-
if (member.id === myUserId.value) return;
|
|
1502
|
-
if (collaborators.value.some((c) => c.id === member.id)) return;
|
|
1503
|
-
const collaborator = {
|
|
1504
|
-
id: member.id,
|
|
1505
|
-
name: member.name,
|
|
1506
|
-
color: assignColor(),
|
|
1507
|
-
selectedBlockId: null
|
|
1508
|
-
};
|
|
1509
|
-
collaborators.value = [...collaborators.value, collaborator];
|
|
1510
|
-
return collaborator;
|
|
1511
|
-
}
|
|
1512
|
-
function removeCollaborator(memberId) {
|
|
1513
|
-
const newLockedBlocks = new Map(lockedBlocks.value);
|
|
1514
|
-
for (const [blockId, collaborator] of newLockedBlocks) if (collaborator.id === memberId) newLockedBlocks.delete(blockId);
|
|
1515
|
-
lockedBlocks.value = newLockedBlocks;
|
|
1516
|
-
collaborators.value = collaborators.value.filter((c) => c.id !== memberId);
|
|
1517
|
-
}
|
|
1518
|
-
function handleBlockLocked(data) {
|
|
1519
|
-
const collaborator = collaborators.value.find((c) => c.id === data.userId);
|
|
1520
|
-
if (!collaborator) return;
|
|
1521
|
-
collaborators.value = collaborators.value.map((c) => c.id === data.userId ? {
|
|
1522
|
-
...c,
|
|
1523
|
-
selectedBlockId: data.blockId
|
|
1524
|
-
} : c);
|
|
1525
|
-
const newLockedBlocks = new Map(lockedBlocks.value);
|
|
1526
|
-
for (const [blockId, holder] of newLockedBlocks) if (holder.id === data.userId) newLockedBlocks.delete(blockId);
|
|
1527
|
-
newLockedBlocks.set(data.blockId, {
|
|
1528
|
-
...collaborator,
|
|
1529
|
-
selectedBlockId: data.blockId
|
|
1530
|
-
});
|
|
1531
|
-
lockedBlocks.value = newLockedBlocks;
|
|
1532
|
-
if (editor.state.selectedBlockId === data.blockId) editor.selectBlock(null);
|
|
1533
|
-
}
|
|
1534
|
-
function handleBlockUnlocked(data) {
|
|
1535
|
-
const newLockedBlocks = new Map(lockedBlocks.value);
|
|
1536
|
-
const holder = newLockedBlocks.get(data.blockId);
|
|
1537
|
-
newLockedBlocks.delete(data.blockId);
|
|
1538
|
-
lockedBlocks.value = newLockedBlocks;
|
|
1539
|
-
if (holder) collaborators.value = collaborators.value.map((c) => c.id === holder.id ? {
|
|
1540
|
-
...c,
|
|
1541
|
-
selectedBlockId: null
|
|
1542
|
-
} : c);
|
|
1543
|
-
}
|
|
1544
|
-
function handleRemoteOperation(payload) {
|
|
1545
|
-
isProcessingRemoteOperation = true;
|
|
1546
|
-
try {
|
|
1547
|
-
handleOperation(editor, payload);
|
|
1548
|
-
} finally {
|
|
1549
|
-
isProcessingRemoteOperation = false;
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
function broadcastOperation(payload) {
|
|
1553
|
-
if (!channel.value || isProcessingRemoteOperation) return;
|
|
1554
|
-
channel.value.trigger("client-operation", payload);
|
|
1555
|
-
}
|
|
1556
|
-
function broadcastBlockLocked(blockId) {
|
|
1557
|
-
if (!channel.value) return;
|
|
1558
|
-
channel.value.trigger("client-blockLocked", {
|
|
1559
|
-
blockId,
|
|
1560
|
-
userId: myUserId.value
|
|
1561
|
-
});
|
|
1562
|
-
}
|
|
1563
|
-
function broadcastBlockUnlocked(blockId) {
|
|
1564
|
-
if (!channel.value) return;
|
|
1565
|
-
channel.value.trigger("client-blockUnlocked", { blockId });
|
|
1566
|
-
}
|
|
1567
|
-
watch(() => editor.state.selectedBlockId, (newBlockId, oldBlockId) => {
|
|
1568
|
-
if (isProcessingRemoteOperation) return;
|
|
1569
|
-
if (oldBlockId) broadcastBlockUnlocked(oldBlockId);
|
|
1570
|
-
if (newBlockId) broadcastBlockLocked(newBlockId);
|
|
1571
|
-
});
|
|
1572
|
-
watch(channel, (newChannel, oldChannel) => {
|
|
1573
|
-
if (oldChannel) unbindCollabEvents(oldChannel);
|
|
1574
|
-
if (!newChannel) {
|
|
1575
|
-
collaborators.value = [];
|
|
1576
|
-
lockedBlocks.value = /* @__PURE__ */ new Map();
|
|
1577
|
-
colorIndex = 0;
|
|
1578
|
-
return;
|
|
1579
|
-
}
|
|
1580
|
-
const members = newChannel.members;
|
|
1581
|
-
if (members) members.each((member) => {
|
|
1582
|
-
addCollaborator(member.info);
|
|
1583
|
-
});
|
|
1584
|
-
newChannel.bind("pusher:member_added", (member) => {
|
|
1585
|
-
const collaborator = addCollaborator(member.info);
|
|
1586
|
-
if (collaborator) options.onCollaboratorJoined?.(collaborator);
|
|
1587
|
-
});
|
|
1588
|
-
newChannel.bind("pusher:member_removed", (member) => {
|
|
1589
|
-
const collaborator = collaborators.value.find((c) => c.id === member.id);
|
|
1590
|
-
removeCollaborator(member.id);
|
|
1591
|
-
if (collaborator) options.onCollaboratorLeft?.(collaborator);
|
|
1592
|
-
});
|
|
1593
|
-
newChannel.bind("client-blockLocked", (data) => {
|
|
1594
|
-
handleBlockLocked(data);
|
|
1595
|
-
const collaborator = collaborators.value.find((c) => c.id === data.userId);
|
|
1596
|
-
if (collaborator) options.onBlockLocked?.({
|
|
1597
|
-
blockId: data.blockId,
|
|
1598
|
-
collaborator
|
|
1599
|
-
});
|
|
1600
|
-
});
|
|
1601
|
-
newChannel.bind("client-blockUnlocked", (data) => {
|
|
1602
|
-
const holder = lockedBlocks.value.get(data.blockId);
|
|
1603
|
-
handleBlockUnlocked(data);
|
|
1604
|
-
if (holder) options.onBlockUnlocked?.({
|
|
1605
|
-
blockId: data.blockId,
|
|
1606
|
-
collaborator: holder
|
|
1607
|
-
});
|
|
1608
|
-
});
|
|
1609
|
-
newChannel.bind("client-operation", (payload) => {
|
|
1610
|
-
handleRemoteOperation(payload);
|
|
1611
|
-
});
|
|
1612
|
-
newChannel.bind("mcp-operation", (payload) => {
|
|
1613
|
-
handleRemoteOperation(payload);
|
|
1614
|
-
});
|
|
1615
|
-
});
|
|
1616
|
-
onScopeDispose(() => {
|
|
1617
|
-
if (channel.value) unbindCollabEvents(channel.value);
|
|
1618
|
-
});
|
|
1619
|
-
return {
|
|
1620
|
-
collaborators,
|
|
1621
|
-
lockedBlocks,
|
|
1622
|
-
_broadcastOperation: broadcastOperation,
|
|
1623
|
-
_isProcessingRemoteOperation: () => isProcessingRemoteOperation
|
|
1624
|
-
};
|
|
1625
|
-
}
|
|
1626
|
-
//#endregion
|
|
1627
|
-
//#region src/cloud/collaboration-broadcast.ts
|
|
1628
|
-
/**
|
|
1629
|
-
* Wraps editor mutation methods to broadcast operations to collaboration
|
|
1630
|
-
* peers after each mutation executes. Mutates the editor object in place.
|
|
1631
|
-
*
|
|
1632
|
-
* Must be applied **before** the history interceptor so the call chain is:
|
|
1633
|
-
* history.record() → broadcast + original mutation.
|
|
1634
|
-
*/
|
|
1635
|
-
function useCollaborationBroadcast(editor, collaboration) {
|
|
1636
|
-
const originalAddBlock = editor.addBlock;
|
|
1637
|
-
const originalUpdateBlock = editor.updateBlock;
|
|
1638
|
-
const originalRemoveBlock = editor.removeBlock;
|
|
1639
|
-
const originalMoveBlock = editor.moveBlock;
|
|
1640
|
-
const originalUpdateSettings = editor.updateSettings;
|
|
1641
|
-
const originalSetContent = editor.setContent;
|
|
1642
|
-
editor.addBlock = (block, targetSectionId, columnIndex, index) => {
|
|
1643
|
-
originalAddBlock(block, targetSectionId, columnIndex, index);
|
|
1644
|
-
collaboration._broadcastOperation({
|
|
1645
|
-
operation: "addBlock",
|
|
1646
|
-
data: {
|
|
1647
|
-
block,
|
|
1648
|
-
sectionId: targetSectionId,
|
|
1649
|
-
columnIndex,
|
|
1650
|
-
index
|
|
1651
|
-
},
|
|
1652
|
-
timestamp: Date.now()
|
|
1653
|
-
});
|
|
1654
|
-
};
|
|
1655
|
-
editor.updateBlock = (blockId, updates) => {
|
|
1656
|
-
originalUpdateBlock(blockId, updates);
|
|
1657
|
-
collaboration._broadcastOperation({
|
|
1658
|
-
operation: "updateBlock",
|
|
1659
|
-
data: {
|
|
1660
|
-
blockId,
|
|
1661
|
-
updates
|
|
1662
|
-
},
|
|
1663
|
-
timestamp: Date.now()
|
|
1664
|
-
});
|
|
1665
|
-
};
|
|
1666
|
-
editor.removeBlock = (blockId) => {
|
|
1667
|
-
originalRemoveBlock(blockId);
|
|
1668
|
-
collaboration._broadcastOperation({
|
|
1669
|
-
operation: "deleteBlock",
|
|
1670
|
-
data: { blockId },
|
|
1671
|
-
timestamp: Date.now()
|
|
1672
|
-
});
|
|
1673
|
-
};
|
|
1674
|
-
editor.moveBlock = (blockId, newIndex, targetSectionId, columnIndex) => {
|
|
1675
|
-
originalMoveBlock(blockId, newIndex, targetSectionId, columnIndex);
|
|
1676
|
-
collaboration._broadcastOperation({
|
|
1677
|
-
operation: "moveBlock",
|
|
1678
|
-
data: {
|
|
1679
|
-
blockId,
|
|
1680
|
-
index: newIndex,
|
|
1681
|
-
sectionId: targetSectionId,
|
|
1682
|
-
columnIndex
|
|
1683
|
-
},
|
|
1684
|
-
timestamp: Date.now()
|
|
1685
|
-
});
|
|
1686
|
-
};
|
|
1687
|
-
editor.updateSettings = (updates) => {
|
|
1688
|
-
originalUpdateSettings(updates);
|
|
1689
|
-
collaboration._broadcastOperation({
|
|
1690
|
-
operation: "updateSettings",
|
|
1691
|
-
data: { updates },
|
|
1692
|
-
timestamp: Date.now()
|
|
1693
|
-
});
|
|
1694
|
-
};
|
|
1695
|
-
editor.setContent = (content, markDirty) => {
|
|
1696
|
-
originalSetContent(content, markDirty);
|
|
1697
|
-
collaboration._broadcastOperation({
|
|
1698
|
-
operation: "setContent",
|
|
1699
|
-
data: { content },
|
|
1700
|
-
timestamp: Date.now()
|
|
1701
|
-
});
|
|
1702
|
-
};
|
|
1703
|
-
}
|
|
1704
|
-
//#endregion
|
|
1705
812
|
//#region src/cloud/web-socket.ts
|
|
1706
813
|
function useWebSocket(options) {
|
|
1707
814
|
const { authManager, onError } = options;
|
|
@@ -2357,18 +1464,6 @@ async function performHealthCheck(options = {}) {
|
|
|
2357
1464
|
};
|
|
2358
1465
|
}
|
|
2359
1466
|
//#endregion
|
|
2360
|
-
|
|
2361
|
-
function useMcpListener(options) {
|
|
2362
|
-
const { editor, channel, onOperation } = options;
|
|
2363
|
-
watch(channel, (newChannel, oldChannel) => {
|
|
2364
|
-
if (oldChannel) oldChannel.unbind("mcp-operation");
|
|
2365
|
-
if (newChannel) newChannel.bind("mcp-operation", (payload) => {
|
|
2366
|
-
handleOperation(editor, payload);
|
|
2367
|
-
onOperation?.(payload);
|
|
2368
|
-
});
|
|
2369
|
-
});
|
|
2370
|
-
}
|
|
2371
|
-
//#endregion
|
|
2372
|
-
export { API_ROUTES, ApiClient, AuthManager, MediaApiClient, WebSocketClient, buildUrl, createCloudCommentsProvider, createCloudMediaProvider, createCloudRenderProvider, createCloudSavedBlocksProvider, createCloudTemplatesProvider, createCloudTestEmailProvider, createCloudVersionHistoryProvider, createSdkAuthManager, handleOperation, isFatalAuthError, performHealthCheck, resolveExportFonts, resolveWebSocketConfig, useAiChat, useAiConfig, useAiRewrite, useCollaboration, useCollaborationBroadcast, useDesignReference, useExport, useMcpListener, usePlanConfig, useTemplateScoring, useTestEmail, useWebSocket };
|
|
1467
|
+
export { API_ROUTES, ApiClient, AuthManager, MediaApiClient, WebSocketClient, buildUrl, createCloudCommentsProvider, createCloudMediaProvider, createCloudRenderProvider, createCloudSavedBlocksProvider, createCloudTemplatesProvider, createCloudTestEmailProvider, createCloudVersionHistoryProvider, createSdkAuthManager, isFatalAuthError, performHealthCheck, resolveExportFonts, resolveWebSocketConfig, useExport, usePlanConfig, useTestEmail, useWebSocket };
|
|
2373
1468
|
|
|
2374
1469
|
//# sourceMappingURL=index.js.map
|