fix: second work-over

This commit is contained in:
2026-02-27 09:06:56 +01:00
parent 00cf30a8f8
commit 467ef10e77
11 changed files with 1040 additions and 8 deletions

View File

@@ -15,7 +15,7 @@ import { createDeferredEventGate } from './navigation/deferredEventGate';
import { createAndFocusPost } from './navigation/postCreation';
import { ensureRendererPicoThemeStylesheet, getRendererPicoTheme } from './utils/picoTheme';
import { addWindowEventListener, BDS_EVENT_SCRIPTS_CHANGED } from './utils/windowEvents';
import { refreshPythonMacroSlugs } from './macros';
import { refreshPythonMacroSlugs, wirePythonMacroPreview, invalidatePythonMacroScriptCache } from './macros';
import { useI18n } from './i18n';
import './App.css';
@@ -109,6 +109,9 @@ const App: React.FC = () => {
// Load known Python macro slugs for editor detection
await refreshPythonMacroSlugs();
// Wire Python macro resolver/renderer for editor preview
wirePythonMacroPreview();
} catch (error) {
console.error('Failed to load initial data:', error);
} finally {
@@ -565,6 +568,7 @@ const App: React.FC = () => {
// Refresh Python macro slugs when scripts change
unsubscribers.push(
addWindowEventListener(BDS_EVENT_SCRIPTS_CHANGED, () => {
invalidatePythonMacroScriptCache();
void refreshPythonMacroSlugs();
})
);

View File

@@ -45,3 +45,8 @@ export {
setPythonMacroResolver,
refreshPythonMacroSlugs,
} from './registry';
export {
wirePythonMacroPreview,
invalidatePythonMacroScriptCache,
} from './pythonMacroPreview';

View File

@@ -0,0 +1,72 @@
import type { PythonMacroInfo, PythonMacroResolver, PythonMacroRendererFn } from './types';
import { setPythonMacroResolver } from './registry';
import { getPythonRuntimeManager } from '../python/runtimeManagerInstance';
interface ScriptLike {
id: string;
slug: string;
kind: string;
enabled: boolean;
content: string;
entrypoint: string;
version: number;
}
let cachedMacroScripts: ScriptLike[] | null = null;
export function invalidatePythonMacroScriptCache(): void {
cachedMacroScripts = null;
}
async function loadMacroScripts(): Promise<ScriptLike[]> {
if (cachedMacroScripts) return cachedMacroScripts;
const allScripts = await window.electronAPI?.scripts.getAll();
cachedMacroScripts = (allScripts ?? []).filter(
(s: ScriptLike) => s.kind === 'macro' && s.enabled,
);
return cachedMacroScripts;
}
const resolvePythonMacro: PythonMacroResolver = async (macroName) => {
const scripts = await loadMacroScripts();
const lower = macroName.toLowerCase();
const script = scripts.find((s) => s.slug.toLowerCase() === lower);
if (!script) return null;
return {
scriptId: script.id,
slug: script.slug,
code: script.content,
entrypoint: script.entrypoint,
version: script.version,
};
};
const renderPythonMacro: PythonMacroRendererFn = async (info, params, context) => {
const manager = getPythonRuntimeManager();
const macroContext = {
env: {
isPreview: context.isPreview,
source: { kind: 'script', id: info.scriptId },
},
params: params as Record<string, unknown>,
};
const result = await manager.renderMacroV1(info.code, macroContext, {
entrypoint: info.entrypoint,
cacheKey: `${info.scriptId}:v${info.version}`,
macroSource: { kind: 'script', id: info.scriptId },
});
return result.result.html;
};
/**
* Wire the Python macro resolver and renderer into the macro registry
* so that the editor preview can render Python-backed macros.
* Call once on startup after refreshPythonMacroSlugs().
*/
export function wirePythonMacroPreview(): void {
setPythonMacroResolver(resolvePythonMacro, renderPythonMacro);
}