mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 08:51:23 +00:00
Canvas: improve A2UI asset resolution and empty state (#20312)
Merged via /review-pr -> /prepare-pr -> /merge-pr.
Prepared head SHA: adce485695
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
This commit is contained in:
@@ -13,14 +13,29 @@ export const CANVAS_WS_PATH = "/__openclaw__/ws";
|
||||
|
||||
let cachedA2uiRootReal: string | null | undefined;
|
||||
let resolvingA2uiRoot: Promise<string | null> | null = null;
|
||||
let cachedA2uiResolvedAtMs = 0;
|
||||
const A2UI_ROOT_RETRY_NULL_AFTER_MS = 10_000;
|
||||
|
||||
async function resolveA2uiRoot(): Promise<string | null> {
|
||||
const here = path.dirname(fileURLToPath(import.meta.url));
|
||||
const entryDir = process.argv[1] ? path.dirname(path.resolve(process.argv[1])) : null;
|
||||
const candidates = [
|
||||
// Running from source (bun) or dist (tsc + copied assets).
|
||||
// Running from source (bun) or dist/canvas-host chunk.
|
||||
path.resolve(here, "a2ui"),
|
||||
// Running from dist root chunk (common launchd path).
|
||||
path.resolve(here, "canvas-host/a2ui"),
|
||||
path.resolve(here, "../canvas-host/a2ui"),
|
||||
// Entry path fallbacks (helps when cwd is not the repo root).
|
||||
...(entryDir
|
||||
? [
|
||||
path.resolve(entryDir, "a2ui"),
|
||||
path.resolve(entryDir, "canvas-host/a2ui"),
|
||||
path.resolve(entryDir, "../canvas-host/a2ui"),
|
||||
]
|
||||
: []),
|
||||
// Running from dist without copied assets (fallback to source).
|
||||
path.resolve(here, "../../src/canvas-host/a2ui"),
|
||||
path.resolve(here, "../src/canvas-host/a2ui"),
|
||||
// Running from repo root.
|
||||
path.resolve(process.cwd(), "src/canvas-host/a2ui"),
|
||||
path.resolve(process.cwd(), "dist/canvas-host/a2ui"),
|
||||
@@ -44,13 +59,19 @@ async function resolveA2uiRoot(): Promise<string | null> {
|
||||
}
|
||||
|
||||
async function resolveA2uiRootReal(): Promise<string | null> {
|
||||
if (cachedA2uiRootReal !== undefined) {
|
||||
const nowMs = Date.now();
|
||||
if (
|
||||
cachedA2uiRootReal !== undefined &&
|
||||
(cachedA2uiRootReal !== null || nowMs - cachedA2uiResolvedAtMs < A2UI_ROOT_RETRY_NULL_AFTER_MS)
|
||||
) {
|
||||
return cachedA2uiRootReal;
|
||||
}
|
||||
if (!resolvingA2uiRoot) {
|
||||
resolvingA2uiRoot = (async () => {
|
||||
const root = await resolveA2uiRoot();
|
||||
cachedA2uiRootReal = root ? await fs.realpath(root) : null;
|
||||
cachedA2uiResolvedAtMs = Date.now();
|
||||
resolvingA2uiRoot = null;
|
||||
return cachedA2uiRootReal;
|
||||
})();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user