dsh-workbuddy-files 0.1.1 → 0.1.3
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/lib/client.js +101 -69
- package/package.json +1 -1
- package/src/client/app.ts +39 -7
package/lib/client.js
CHANGED
|
@@ -900,81 +900,113 @@
|
|
|
900
900
|
const React = require("react");
|
|
901
901
|
return {
|
|
902
902
|
name: "workbuddy-files",
|
|
903
|
+
inject: [
|
|
904
|
+
"slots",
|
|
905
|
+
"sessions",
|
|
906
|
+
"conversation"
|
|
907
|
+
],
|
|
903
908
|
apply(ctx) {
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
const inputTriggers = get("inputTriggers");
|
|
909
|
-
const conversationEvents = get("conversationEvents");
|
|
910
|
-
const styles = get("styles");
|
|
911
|
-
if (slots === void 0) return;
|
|
912
|
-
const insertStyles = () => styles !== void 0 ? styles.insert(CSS) : () => {};
|
|
913
|
-
const effect = ctx.effect.bind(ctx);
|
|
914
|
-
effect(insertStyles, "workbuddy: styles");
|
|
915
|
-
const bus = createDropBus();
|
|
916
|
-
let rootCache = null;
|
|
917
|
-
dropsHome().then((r) => {
|
|
918
|
-
rootCache = r;
|
|
919
|
-
});
|
|
920
|
-
const ensureRoot = async () => {
|
|
921
|
-
if (rootCache !== null) return rootCache;
|
|
922
|
-
const r = await dropsHome();
|
|
923
|
-
rootCache = r;
|
|
924
|
-
return r;
|
|
925
|
-
};
|
|
926
|
-
const enqueueUpload = (jobs, batch) => {
|
|
927
|
-
runUploadJobs(jobs, batch).then(({ ok, failed }) => {
|
|
928
|
-
if (failed.length > 0) bus.toast("缓存失败 " + failed.length + " 项:" + failed.slice(0, 2).join(";") + (failed.length > 2 ? "…" : ""), "error");
|
|
929
|
-
else if (ok > 0) bus.toast("后台缓存完成:" + ok + " 个文件已就绪");
|
|
930
|
-
}).catch((err) => {
|
|
931
|
-
bus.toast("后台缓存失败:" + String(err?.message ?? err), "error");
|
|
932
|
-
});
|
|
933
|
-
};
|
|
934
|
-
const handlers = createDropHandlers({
|
|
935
|
-
bus,
|
|
936
|
-
insert: createInsertPipeline({
|
|
937
|
-
sessions,
|
|
938
|
-
conversation,
|
|
939
|
-
toast: bus.toast
|
|
940
|
-
}),
|
|
941
|
-
ensureRoot,
|
|
942
|
-
enqueueUpload
|
|
943
|
-
});
|
|
944
|
-
effect(() => handlers.installListeners(), "workbuddy: window listeners");
|
|
945
|
-
if (inputTriggers !== void 0) {
|
|
946
|
-
const source = createAtSource();
|
|
947
|
-
effect(() => inputTriggers.registerSource(source), "workbuddy: @ source");
|
|
909
|
+
try {
|
|
910
|
+
applyClient(ctx, React);
|
|
911
|
+
} catch (err) {
|
|
912
|
+
console.error("[workbuddy-files] client apply 异常:", err);
|
|
948
913
|
}
|
|
949
|
-
if (conversationEvents !== void 0) effect(() => {
|
|
950
|
-
const d1 = conversationEvents.register(boundaryDef);
|
|
951
|
-
const d2 = conversationEvents.register(fileRefsDef);
|
|
952
|
-
return () => {
|
|
953
|
-
if (typeof d1 === "function") d1();
|
|
954
|
-
if (typeof d2 === "function") d2();
|
|
955
|
-
};
|
|
956
|
-
}, "workbuddy: conversation definitions");
|
|
957
|
-
slots.inject("shell.overlay", () => slots.register({
|
|
958
|
-
name: "shell.overlay",
|
|
959
|
-
id: "workbuddy-drop",
|
|
960
|
-
order: 300,
|
|
961
|
-
label: "WorkBuddy 拖拽遮罩"
|
|
962
|
-
}, createOverlayComponent(React, bus)));
|
|
963
|
-
slots.inject("conversation.input.left", () => slots.register({
|
|
964
|
-
name: "conversation.input.left",
|
|
965
|
-
id: "workbuddy-pick",
|
|
966
|
-
order: 0,
|
|
967
|
-
label: "引用文件/文件夹"
|
|
968
|
-
}, createPickButtonComponent(React, bus, handlers)));
|
|
969
|
-
slots.inject("conversation.chat.turnTail", () => slots.register({
|
|
970
|
-
name: "conversation.chat.turnTail",
|
|
971
|
-
select: selectTurnFileRefs
|
|
972
|
-
}, createFileCardsComponent(React)));
|
|
973
|
-
console.log("[workbuddy-files] client 就绪:拖入即插气泡 + 后台缓存 / 统一遮罩 / 文件卡片");
|
|
974
914
|
}
|
|
975
915
|
};
|
|
976
916
|
};
|
|
977
917
|
}
|
|
918
|
+
function applyClient(ctx, React) {
|
|
919
|
+
console.log("[workbuddy-files] client apply 开始");
|
|
920
|
+
const get = (name) => ctx.get(name);
|
|
921
|
+
const sessions = get("sessions");
|
|
922
|
+
const slots = get("slots");
|
|
923
|
+
const conversation = get("conversation");
|
|
924
|
+
const inputTriggers = get("inputTriggers");
|
|
925
|
+
const conversationEvents = get("conversationEvents");
|
|
926
|
+
const styles = get("styles");
|
|
927
|
+
if (slots === void 0) return;
|
|
928
|
+
const injectCssViaHead = (css) => {
|
|
929
|
+
if (typeof document === "undefined") return;
|
|
930
|
+
const tagId = "dsh-workbuddy-files/styles";
|
|
931
|
+
if (document.querySelector("style[data-plugin-css=\"" + tagId + "\"]") !== null) return;
|
|
932
|
+
const tag = document.createElement("style");
|
|
933
|
+
tag.dataset.plugin = "dsh-workbuddy-files";
|
|
934
|
+
tag.dataset.pluginCss = tagId;
|
|
935
|
+
tag.textContent = css;
|
|
936
|
+
document.head.appendChild(tag);
|
|
937
|
+
};
|
|
938
|
+
const insertStyles = () => {
|
|
939
|
+
if (styles !== void 0) return styles.insert(CSS);
|
|
940
|
+
injectCssViaHead(CSS);
|
|
941
|
+
return () => {};
|
|
942
|
+
};
|
|
943
|
+
const effect = ctx.effect.bind(ctx);
|
|
944
|
+
effect(insertStyles, "workbuddy: styles");
|
|
945
|
+
console.log("[workbuddy-files] client apply 开始:services slots=" + (slots !== void 0) + " conversation=" + (conversation !== void 0) + " inputTriggers=" + (inputTriggers !== void 0) + " conversationEvents=" + (conversationEvents !== void 0) + " styles=" + (styles !== void 0));
|
|
946
|
+
const bus = createDropBus();
|
|
947
|
+
let rootCache = null;
|
|
948
|
+
dropsHome().then((r) => {
|
|
949
|
+
rootCache = r;
|
|
950
|
+
});
|
|
951
|
+
const ensureRoot = async () => {
|
|
952
|
+
if (rootCache !== null) return rootCache;
|
|
953
|
+
const r = await dropsHome();
|
|
954
|
+
rootCache = r;
|
|
955
|
+
return r;
|
|
956
|
+
};
|
|
957
|
+
const enqueueUpload = (jobs, batch) => {
|
|
958
|
+
runUploadJobs(jobs, batch).then(({ ok, failed }) => {
|
|
959
|
+
if (failed.length > 0) bus.toast("缓存失败 " + failed.length + " 项:" + failed.slice(0, 2).join(";") + (failed.length > 2 ? "…" : ""), "error");
|
|
960
|
+
else if (ok > 0) bus.toast("后台缓存完成:" + ok + " 个文件已就绪");
|
|
961
|
+
}).catch((err) => {
|
|
962
|
+
bus.toast("后台缓存失败:" + String(err?.message ?? err), "error");
|
|
963
|
+
});
|
|
964
|
+
};
|
|
965
|
+
const handlers = createDropHandlers({
|
|
966
|
+
bus,
|
|
967
|
+
insert: createInsertPipeline({
|
|
968
|
+
sessions,
|
|
969
|
+
conversation,
|
|
970
|
+
toast: bus.toast
|
|
971
|
+
}),
|
|
972
|
+
ensureRoot,
|
|
973
|
+
enqueueUpload
|
|
974
|
+
});
|
|
975
|
+
effect(() => {
|
|
976
|
+
const off = handlers.installListeners();
|
|
977
|
+
console.log("[workbuddy-files] 窗口拖拽/粘贴监听已注册");
|
|
978
|
+
return off;
|
|
979
|
+
}, "workbuddy: window listeners");
|
|
980
|
+
if (inputTriggers !== void 0) {
|
|
981
|
+
const source = createAtSource();
|
|
982
|
+
effect(() => inputTriggers.registerSource(source), "workbuddy: @ source");
|
|
983
|
+
}
|
|
984
|
+
if (conversationEvents !== void 0) effect(() => {
|
|
985
|
+
const d1 = conversationEvents.register(boundaryDef);
|
|
986
|
+
const d2 = conversationEvents.register(fileRefsDef);
|
|
987
|
+
return () => {
|
|
988
|
+
if (typeof d1 === "function") d1();
|
|
989
|
+
if (typeof d2 === "function") d2();
|
|
990
|
+
};
|
|
991
|
+
}, "workbuddy: conversation definitions");
|
|
992
|
+
slots.inject("shell.overlay", () => slots.register({
|
|
993
|
+
name: "shell.overlay",
|
|
994
|
+
id: "workbuddy-drop",
|
|
995
|
+
order: 300,
|
|
996
|
+
label: "WorkBuddy 拖拽遮罩"
|
|
997
|
+
}, createOverlayComponent(React, bus)));
|
|
998
|
+
slots.inject("conversation.input.left", () => slots.register({
|
|
999
|
+
name: "conversation.input.left",
|
|
1000
|
+
id: "workbuddy-pick",
|
|
1001
|
+
order: 0,
|
|
1002
|
+
label: "引用文件/文件夹"
|
|
1003
|
+
}, createPickButtonComponent(React, bus, handlers)));
|
|
1004
|
+
slots.inject("conversation.chat.turnTail", () => slots.register({
|
|
1005
|
+
name: "conversation.chat.turnTail",
|
|
1006
|
+
select: selectTurnFileRefs
|
|
1007
|
+
}, createFileCardsComponent(React)));
|
|
1008
|
+
console.log("[workbuddy-files] client 就绪:拖入即插气泡 + 后台缓存 / 统一遮罩 / 文件卡片");
|
|
1009
|
+
}
|
|
978
1010
|
//#endregion
|
|
979
1011
|
//#region src/client/index.ts
|
|
980
1012
|
window.__ModuleLoader__.load({
|
package/package.json
CHANGED
package/src/client/app.ts
CHANGED
|
@@ -24,7 +24,8 @@ import type { UploadJob } from './types'
|
|
|
24
24
|
/** 工厂返回的 Cordis 客户端插件 */
|
|
25
25
|
export interface ClientPlugin {
|
|
26
26
|
apply(ctx: Record<string, unknown>): void
|
|
27
|
-
|
|
27
|
+
/** 硬依赖:Cordis 会等这些服务就绪后再 apply(缺失即无限等待,不会静默跳过) */
|
|
28
|
+
inject: string[]
|
|
28
29
|
name?: string
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -34,8 +35,22 @@ export function makeFactory() {
|
|
|
34
35
|
|
|
35
36
|
return {
|
|
36
37
|
name: 'workbuddy-files',
|
|
38
|
+
// slots:UI 注册入口;sessions + conversation:气泡插入管线核心
|
|
39
|
+
inject: ['slots', 'sessions', 'conversation'],
|
|
37
40
|
apply(ctx) {
|
|
38
|
-
|
|
41
|
+
try {
|
|
42
|
+
applyClient(ctx, React)
|
|
43
|
+
} catch (err) {
|
|
44
|
+
console.error('[workbuddy-files] client apply 异常:', err)
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function applyClient(ctx: Record<string, unknown>, React: ReactLike): void {
|
|
52
|
+
console.log('[workbuddy-files] client apply 开始')
|
|
53
|
+
const get = (name: string) => (ctx.get as (n: string) => unknown)(name)
|
|
39
54
|
|
|
40
55
|
// ---- 能力探测(缺失则优雅退出)----
|
|
41
56
|
const sessions = get('sessions') as never
|
|
@@ -54,9 +69,25 @@ export function makeFactory() {
|
|
|
54
69
|
if (slots === undefined) return
|
|
55
70
|
|
|
56
71
|
// ---- 包内样式 ----
|
|
57
|
-
|
|
72
|
+
// 正式插件包没有动态版的 styles 内置服务:回退到 document.head style 注入(dsh-pet 同款)
|
|
73
|
+
const injectCssViaHead = (css: string): void => {
|
|
74
|
+
if (typeof document === 'undefined') return
|
|
75
|
+
const tagId = 'dsh-workbuddy-files/styles'
|
|
76
|
+
if (document.querySelector('style[data-plugin-css="' + tagId + '"]') !== null) return
|
|
77
|
+
const tag = document.createElement('style')
|
|
78
|
+
tag.dataset.plugin = 'dsh-workbuddy-files'
|
|
79
|
+
tag.dataset.pluginCss = tagId
|
|
80
|
+
tag.textContent = css
|
|
81
|
+
document.head.appendChild(tag)
|
|
82
|
+
}
|
|
83
|
+
const insertStyles = () => {
|
|
84
|
+
if (styles !== undefined) return styles.insert(CSS)
|
|
85
|
+
injectCssViaHead(CSS)
|
|
86
|
+
return () => {}
|
|
87
|
+
}
|
|
58
88
|
const effect = (ctx.effect as (fn: () => (() => void) | undefined, label?: string) => void).bind(ctx)
|
|
59
89
|
effect(insertStyles, 'workbuddy: styles')
|
|
90
|
+
console.log('[workbuddy-files] client apply 开始:services slots=' + (slots !== undefined) + ' conversation=' + (conversation !== undefined) + ' inputTriggers=' + (inputTriggers !== undefined) + ' conversationEvents=' + (conversationEvents !== undefined) + ' styles=' + (styles !== undefined))
|
|
60
91
|
|
|
61
92
|
// ---- 共享实例 ----
|
|
62
93
|
const bus = createDropBus()
|
|
@@ -89,7 +120,11 @@ export function makeFactory() {
|
|
|
89
120
|
|
|
90
121
|
// ---- 拖拽 / 粘贴处理 + 窗口级监听 ----
|
|
91
122
|
const handlers = createDropHandlers({ bus, insert, ensureRoot, enqueueUpload })
|
|
92
|
-
effect(() =>
|
|
123
|
+
effect(() => {
|
|
124
|
+
const off = handlers.installListeners()
|
|
125
|
+
console.log('[workbuddy-files] 窗口拖拽/粘贴监听已注册')
|
|
126
|
+
return off
|
|
127
|
+
}, 'workbuddy: window listeners')
|
|
93
128
|
|
|
94
129
|
// ---- @ 触发源(文件缓存分组)----
|
|
95
130
|
if (inputTriggers !== undefined) {
|
|
@@ -124,7 +159,4 @@ export function makeFactory() {
|
|
|
124
159
|
))
|
|
125
160
|
|
|
126
161
|
console.log('[workbuddy-files] client 就绪:拖入即插气泡 + 后台缓存 / 统一遮罩 / 文件卡片')
|
|
127
|
-
},
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
162
|
}
|