mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 10:50:44 +00:00
Merged via squash.
Prepared head SHA: e8d6738fd0
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
98 lines
3.0 KiB
TypeScript
98 lines
3.0 KiB
TypeScript
export type { PluginRuntime } from "../plugins/runtime/types.js";
|
|
|
|
const pluginRuntimeStoreRegistryKey = Symbol.for("openclaw.plugin-sdk.runtime-store-registry");
|
|
|
|
type PluginRuntimeStoreRegistry = Map<string, { runtime: unknown }>;
|
|
type PluginRuntimeStoreKeyOptions = {
|
|
key: string;
|
|
errorMessage: string;
|
|
};
|
|
type PluginRuntimeStorePluginOptions = {
|
|
pluginId: string;
|
|
errorMessage: string;
|
|
};
|
|
type PluginRuntimeStoreOptions = PluginRuntimeStoreKeyOptions | PluginRuntimeStorePluginOptions;
|
|
|
|
function getPluginRuntimeStoreRegistry(): PluginRuntimeStoreRegistry {
|
|
const globalRecord = globalThis as typeof globalThis & {
|
|
[pluginRuntimeStoreRegistryKey]?: PluginRuntimeStoreRegistry;
|
|
};
|
|
globalRecord[pluginRuntimeStoreRegistryKey] ??= new Map();
|
|
return globalRecord[pluginRuntimeStoreRegistryKey];
|
|
}
|
|
|
|
function pluginRuntimeStoreKeyForPluginId(pluginId: string): string {
|
|
const normalizedPluginId = pluginId.trim();
|
|
if (!normalizedPluginId) {
|
|
throw new Error("createPluginRuntimeStore: pluginId must not be empty");
|
|
}
|
|
return `plugin-runtime:${normalizedPluginId}`;
|
|
}
|
|
|
|
function resolvePluginRuntimeStoreOptions(
|
|
options: string | PluginRuntimeStoreOptions,
|
|
): PluginRuntimeStoreKeyOptions {
|
|
if (typeof options === "string") {
|
|
return { key: options, errorMessage: options };
|
|
}
|
|
if ("pluginId" in options) {
|
|
return {
|
|
key: pluginRuntimeStoreKeyForPluginId(options.pluginId),
|
|
errorMessage: options.errorMessage,
|
|
};
|
|
}
|
|
return options;
|
|
}
|
|
|
|
/** Create a tiny mutable runtime slot with strict access when the runtime has not been initialized. */
|
|
export function createPluginRuntimeStore<T>(errorMessage: string): {
|
|
setRuntime: (next: T) => void;
|
|
clearRuntime: () => void;
|
|
tryGetRuntime: () => T | null;
|
|
getRuntime: () => T;
|
|
};
|
|
export function createPluginRuntimeStore<T>(options: PluginRuntimeStoreOptions): {
|
|
setRuntime: (next: T) => void;
|
|
clearRuntime: () => void;
|
|
tryGetRuntime: () => T | null;
|
|
getRuntime: () => T;
|
|
};
|
|
export function createPluginRuntimeStore<T>(options: string | PluginRuntimeStoreOptions): {
|
|
setRuntime: (next: T) => void;
|
|
clearRuntime: () => void;
|
|
tryGetRuntime: () => T | null;
|
|
getRuntime: () => T;
|
|
} {
|
|
const resolved = resolvePluginRuntimeStoreOptions(options);
|
|
const slot =
|
|
typeof options === "string"
|
|
? { runtime: null }
|
|
: (() => {
|
|
const registry = getPluginRuntimeStoreRegistry();
|
|
let existingSlot = registry.get(resolved.key);
|
|
if (!existingSlot) {
|
|
existingSlot = { runtime: null };
|
|
registry.set(resolved.key, existingSlot);
|
|
}
|
|
return existingSlot;
|
|
})();
|
|
|
|
return {
|
|
setRuntime(next: T) {
|
|
slot.runtime = next;
|
|
},
|
|
clearRuntime() {
|
|
slot.runtime = null;
|
|
},
|
|
tryGetRuntime() {
|
|
return (slot.runtime as T | null) ?? null;
|
|
},
|
|
getRuntime() {
|
|
if (slot.runtime === null) {
|
|
throw new Error(resolved.errorMessage);
|
|
}
|
|
return slot.runtime as T;
|
|
},
|
|
};
|
|
}
|