




















@@ -1,5 +1,5 @@
11import { createDedupeCache, resolveGlobalDedupeCache } from "../infra/dedupe.js";
2-import { resolveGlobalSingleton } from "../shared/global-singleton.js";
2+import type { DedupeCache } from "../infra/dedupe.js";
33import type { PluginInteractiveHandlerRegistration } from "./types.js";
4455export type RegisteredInteractiveHandler = PluginInteractiveHandlerRegistration & {
@@ -15,19 +15,56 @@ type InteractiveState = {
1515};
16161717const PLUGIN_INTERACTIVE_STATE_KEY = Symbol.for("openclaw.pluginInteractiveState");
18+const PLUGIN_INTERACTIVE_CALLBACK_DEDUPE_KEY = Symbol.for(
19+"openclaw.pluginInteractiveCallbackDedupe",
20+);
182119-function getState() {
20-return resolveGlobalSingleton<InteractiveState>(PLUGIN_INTERACTIVE_STATE_KEY, () => ({
22+function createInteractiveCallbackDedupe(): DedupeCache {
23+return resolveGlobalDedupeCache(PLUGIN_INTERACTIVE_CALLBACK_DEDUPE_KEY, {
24+ttlMs: 5 * 60_000,
25+maxSize: 4096,
26+});
27+}
28+29+function createInteractiveState(): InteractiveState {
30+return {
2131interactiveHandlers: new Map<string, RegisteredInteractiveHandler>(),
22-callbackDedupe: resolveGlobalDedupeCache(
23-Symbol.for("openclaw.pluginInteractiveCallbackDedupe"),
24-{
25-ttlMs: 5 * 60_000,
26-maxSize: 4096,
27-},
28-),
32+callbackDedupe: createInteractiveCallbackDedupe(),
2933inflightCallbackDedupe: new Set<string>(),
30-}));
34+};
35+}
36+37+function hydrateInteractiveState(value: unknown): InteractiveState {
38+const state =
39+typeof value === "object" && value !== null
40+ ? (value as Partial<InteractiveState>)
41+ : ({} as Partial<InteractiveState>);
42+43+return {
44+interactiveHandlers:
45+state.interactiveHandlers instanceof Map
46+ ? state.interactiveHandlers
47+ : new Map<string, RegisteredInteractiveHandler>(),
48+callbackDedupe: createInteractiveCallbackDedupe(),
49+inflightCallbackDedupe:
50+state.inflightCallbackDedupe instanceof Set
51+ ? state.inflightCallbackDedupe
52+ : new Set<string>(),
53+};
54+}
55+56+function getState() {
57+const globalStore = globalThis as Record<PropertyKey, unknown>;
58+const existing = globalStore[PLUGIN_INTERACTIVE_STATE_KEY];
59+if (existing !== undefined) {
60+const hydrated = hydrateInteractiveState(existing);
61+globalStore[PLUGIN_INTERACTIVE_STATE_KEY] = hydrated;
62+return hydrated;
63+}
64+65+const created = createInteractiveState();
66+globalStore[PLUGIN_INTERACTIVE_STATE_KEY] = created;
67+return created;
3168}
32693370export function getPluginInteractiveHandlersState() {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。