docs: document sdk facade loader contracts

This commit is contained in:
Peter Steinberger
2026-06-04 22:29:06 -04:00
parent de4571da4b
commit 99bb94589b
2 changed files with 16 additions and 0 deletions

View File

@@ -113,19 +113,23 @@ function createLazyFacadeProxyValue<T extends object>(params: {
}) as T;
}
/** Create an object proxy that loads the underlying facade only on first property access. */
export function createLazyFacadeObjectValue<T extends object>(load: () => T): T {
return createLazyFacadeProxyValue({ load, target: {} });
}
/** Create an array proxy that loads the underlying facade only on first array access. */
export function createLazyFacadeArrayValue<T extends readonly unknown[]>(load: () => T): T {
return createLazyFacadeProxyValue({ load, target: [] });
}
/** Resolved public-surface module path plus the filesystem root it must stay within. */
export type FacadeModuleLocation = {
modulePath: string;
boundaryRoot: string;
};
/** Load and cache a facade module after verifying it is inside its declared boundary root. */
export function loadFacadeModuleAtLocationSync<T extends object>(params: {
location: FacadeModuleLocation;
trackedPluginId: string | (() => string);
@@ -181,6 +185,7 @@ export function loadFacadeModuleAtLocationSync<T extends object>(params: {
}
// oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- Dynamic facade loaders use caller-supplied module surface types.
/** Resolve and synchronously load a bundled plugin public surface by plugin dir and artifact name. */
export function loadBundledPluginPublicSurfaceModuleSync<T extends object>(params: {
dirName: string;
artifactBasename: string;
@@ -199,6 +204,7 @@ export function loadBundledPluginPublicSurfaceModuleSync<T extends object>(param
});
}
/** Resolve and asynchronously import a bundled plugin public surface with sync-loader fallback. */
export async function loadBundledPluginPublicSurfaceModule<T extends object>(params: {
dirName: string;
artifactBasename: string;
@@ -249,10 +255,12 @@ export async function loadBundledPluginPublicSurfaceModule<T extends object>(par
}
}
/** List plugin ids whose public facades have been loaded in this process. */
export function listImportedBundledPluginFacadeIds(): string[] {
return [...loadedFacadePluginIds].toSorted((left, right) => left.localeCompare(right));
}
/** Reset facade module caches and test loader overrides. */
export function resetFacadeLoaderStateForTest(): void {
loadedFacadeModules.clear();
loadedFacadePluginIds.clear();
@@ -261,6 +269,7 @@ export function resetFacadeLoaderStateForTest(): void {
cachedOpenClawPackageRoot = undefined;
}
/** Override source transform loader creation for facade-loader tests. */
export function setFacadeLoaderSourceTransformFactoryForTest(
factory: PluginModuleLoaderFactory | undefined,
): void {

View File

@@ -25,6 +25,7 @@ export {
listImportedBundledPluginFacadeIds,
} from "./facade-loader.js";
/** Create a lazy value/function proxy for one property of a facade module. */
export function createLazyFacadeValue<TFacade extends object, K extends keyof TFacade>(
loadFacadeModule: () => TFacade,
key: K,
@@ -189,6 +190,7 @@ function buildFacadeActivationCheckParams(
}
// oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- Dynamic facade loaders use caller-supplied module surface types.
/** Load a bundled or registry-backed plugin public surface, tracking activation ownership. */
export function loadBundledPluginPublicSurfaceModuleSync<T extends object>(
params: BundledPluginPublicSurfaceParams,
): T {
@@ -213,6 +215,7 @@ export function loadBundledPluginPublicSurfaceModuleSync<T extends object>(
});
}
/** Check whether an activated bundled plugin public surface may be loaded. */
export function canLoadActivatedBundledPluginPublicSurface(params: {
dirName: string;
artifactBasename: string;
@@ -224,6 +227,7 @@ export function canLoadActivatedBundledPluginPublicSurface(params: {
}
// oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- Dynamic facade loaders use caller-supplied module surface types.
/** Load an activated plugin public surface or throw when activation policy blocks access. */
export function loadActivatedBundledPluginPublicSurfaceModuleSync<T extends object>(params: {
dirName: string;
artifactBasename: string;
@@ -236,6 +240,7 @@ export function loadActivatedBundledPluginPublicSurfaceModuleSync<T extends obje
}
// oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- Dynamic facade loaders use caller-supplied module surface types.
/** Load an activated plugin public surface, returning null when activation policy blocks access. */
export function tryLoadActivatedBundledPluginPublicSurfaceModuleSync<T extends object>(params: {
dirName: string;
artifactBasename: string;
@@ -250,12 +255,14 @@ export function tryLoadActivatedBundledPluginPublicSurfaceModuleSync<T extends o
return loadBundledPluginPublicSurfaceModuleSync<T>(params);
}
/** Reset facade runtime caches and activation-check test overrides. */
export function resetFacadeRuntimeStateForTest(): void {
resetFacadeLoaderStateForTest();
facadeActivationCheckRuntimeModule = undefined;
facadeActivationCheckRuntimeLoaders.clear();
}
/** Test-only hooks for facade activation and resolution checks. */
export const testing = {
setFacadeActivationCheckRuntimeForTest,
loadFacadeModuleAtLocationSync,