Skip to content

Commit 0e273bd

Browse files
claude: Move executeResult functions from engine to core utilities
Move executeResultIncludes and executeResultEngineDependencies from src/execute/jupyter/jupyter.ts to src/core/jupyter/jupyter.ts. These functions are shared utilities used by multiple engines, not engine-specific logic. Moving them to core breaks a circular dependency: - src/core/quarto-api.ts was importing from src/execute/jupyter/jupyter.ts - src/execute/jupyter/jupyter.ts was importing quartoAPI - This created a cycle: core → execute → core With this change, the dependency flow is now one-way: - Engines (execute/) import from quartoAPI (core/) - quartoAPI imports from core utilities (core/jupyter/) - Core utilities have no dependency on engines This is a prerequisite for implementing true dependency inversion via the registry pattern, which will eliminate remaining circular dependencies. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 12294b6 commit 0e273bd

File tree

3 files changed

+65
-42
lines changed

3 files changed

+65
-42
lines changed

src/core/jupyter/jupyter.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ import {
6161
isCaptionableData,
6262
isDisplayData,
6363
} from "./display-data.ts";
64-
import { extractJupyterWidgetDependencies } from "./widgets.ts";
64+
import {
65+
extractJupyterWidgetDependencies,
66+
includesForJupyterWidgetDependencies,
67+
} from "./widgets.ts";
6568
import { removeAndPreserveHtml } from "./preserve.ts";
6669
import { pandocAsciify, pandocAutoIdentifier } from "../pandoc/pandoc-id.ts";
6770
import { Metadata } from "../../config/types.ts";
@@ -112,6 +115,8 @@ import {
112115
kFigCapLoc,
113116
kHtmlTableProcessing,
114117
kInclude,
118+
kIncludeAfterBody,
119+
kIncludeInHeader,
115120
kLayout,
116121
kLayoutAlign,
117122
kLayoutNcol,
@@ -142,6 +147,7 @@ import {
142147
JupyterOutputStream,
143148
JupyterToMarkdownOptions,
144149
JupyterToMarkdownResult,
150+
JupyterWidgetDependencies,
145151
} from "./types.ts";
146152
import { figuresDir, inputFilesDir } from "../render.ts";
147153
import { lines, trimEmptyLines } from "../lib/text.ts";
@@ -153,8 +159,9 @@ import {
153159
removeIfEmptyDir,
154160
} from "../path.ts";
155161
import { convertToHtmlSpans, hasAnsiEscapeCodes } from "../ansi-colors.ts";
156-
import { kProjectType, EngineProjectContext } from "../../project/types.ts";
162+
import { EngineProjectContext, kProjectType } from "../../project/types.ts";
157163
import { mergeConfigs } from "../config.ts";
164+
import type { PandocIncludes } from "../../execute/types.ts";
158165
import { encodeBase64 } from "encoding/base64";
159166
import {
160167
isHtmlOutput,
@@ -2140,3 +2147,37 @@ function outputTypeCssClass(output_type: string) {
21402147
}
21412148
return `cell-output-${output_type}`;
21422149
}
2150+
2151+
// Engine helper functions for processing execute results
2152+
// These are used by multiple engines (Jupyter, etc.) to handle widget dependencies
2153+
export function executeResultIncludes(
2154+
tempDir: string,
2155+
widgetDependencies?: JupyterWidgetDependencies,
2156+
): PandocIncludes | undefined {
2157+
if (widgetDependencies) {
2158+
const includes: PandocIncludes = {};
2159+
const includeFiles = includesForJupyterWidgetDependencies(
2160+
[widgetDependencies],
2161+
tempDir,
2162+
);
2163+
if (includeFiles.inHeader) {
2164+
includes[kIncludeInHeader] = [includeFiles.inHeader];
2165+
}
2166+
if (includeFiles.afterBody) {
2167+
includes[kIncludeAfterBody] = [includeFiles.afterBody];
2168+
}
2169+
return includes;
2170+
} else {
2171+
return undefined;
2172+
}
2173+
}
2174+
2175+
export function executeResultEngineDependencies(
2176+
widgetDependencies?: JupyterWidgetDependencies,
2177+
): Array<unknown> | undefined {
2178+
if (widgetDependencies) {
2179+
return [widgetDependencies];
2180+
} else {
2181+
return undefined;
2182+
}
2183+
}

src/core/quarto-api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ import { quartoDataDir } from "./appdirs.ts";
5454
import {
5555
executeResultEngineDependencies,
5656
executeResultIncludes,
57-
} from "../execute/jupyter/jupyter.ts";
57+
} from "./jupyter/jupyter.ts";
5858
import { completeMessage, withSpinner } from "./console.ts";
5959
import { checkRender } from "../command/check/check-render.ts";
6060
import type { RenderServiceWithLifetime } from "../command/render/types.ts";

src/execute/jupyter/jupyter.ts

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { error, info } from "../../deno_ral/log.ts";
1313

1414
import * as ld from "../../core/lodash.ts";
1515

16-
1716
import {
1817
kBaseFormat,
1918
kExecuteDaemon,
@@ -186,7 +185,9 @@ title: "Title"
186185
if (caps) {
187186
checkCompleteMessage(kMessage + "OK");
188187
if (conf.jsonResult) {
189-
jupyterJson["capabilities"] = await quarto.jupyter.capabilitiesJson(caps);
188+
jupyterJson["capabilities"] = await quarto.jupyter.capabilitiesJson(
189+
caps,
190+
);
190191
} else {
191192
checkInfoMsg(await quarto.jupyter.capabilitiesMessage(caps, kIndent));
192193
}
@@ -212,7 +213,10 @@ title: "Title"
212213
checkInfoMsg("");
213214
}
214215
} else {
215-
const installMessage = quarto.jupyter.installationMessage(caps, kIndent);
216+
const installMessage = quarto.jupyter.installationMessage(
217+
caps,
218+
kIndent,
219+
);
216220
checkInfoMsg(installMessage);
217221
checkInfoMsg("");
218222
jupyterJson["installed"] = false;
@@ -492,7 +496,9 @@ title: "Title"
492496
// that is coming from a non-qmd source
493497
const preserveCellMetadata =
494498
options.format.render[kNotebookPreserveCells] === true ||
495-
(quarto.format.isHtmlDashboardOutput(options.format.identifier[kBaseFormat]) &&
499+
(quarto.format.isHtmlDashboardOutput(
500+
options.format.identifier[kBaseFormat],
501+
) &&
496502
!quarto.path.isQmdFile(options.target.source));
497503

498504
// NOTE: for perforance reasons the 'nb' is mutated in place
@@ -511,7 +517,9 @@ title: "Title"
511517
toLatex: quarto.format.isLatexOutput(options.format.pandoc),
512518
toMarkdown: quarto.format.isMarkdownOutput(options.format),
513519
toIpynb: quarto.format.isIpynbOutput(options.format.pandoc),
514-
toPresentation: quarto.format.isPresentationOutput(options.format.pandoc),
520+
toPresentation: quarto.format.isPresentationOutput(
521+
options.format.pandoc,
522+
),
515523
figFormat: options.format.execute[kFigFormat],
516524
figDpi: options.format.execute[kFigDpi],
517525
figPos: options.format.render[kFigPos],
@@ -747,7 +755,9 @@ async function ensureYamlKernelspec(
747755
const markdown = target.markdown.value;
748756
const yamlJupyter = quarto.markdownRegex.extractYaml(markdown)?.jupyter;
749757
if (yamlJupyter && typeof yamlJupyter !== "boolean") {
750-
const [yamlKernelspec, _] = await quarto.jupyter.kernelspecFromMarkdown(markdown);
758+
const [yamlKernelspec, _] = await quarto.jupyter.kernelspecFromMarkdown(
759+
markdown,
760+
);
751761
if (yamlKernelspec.name !== kernelspec?.name) {
752762
const nb = quarto.jupyter.fromJSON(Deno.readTextFileSync(target.source));
753763
nb.metadata.kernelspec = yamlKernelspec;
@@ -781,7 +791,11 @@ async function createNotebookforTarget(
781791
target: ExecutionTarget,
782792
project?: EngineProjectContext,
783793
) {
784-
const nb = await quarto.jupyter.quartoMdToJupyter(target.markdown.value, true, project);
794+
const nb = await quarto.jupyter.quartoMdToJupyter(
795+
target.markdown.value,
796+
true,
797+
project,
798+
);
785799
Deno.writeTextFileSync(target.input, JSON.stringify(nb, null, 2));
786800
return nb;
787801
}
@@ -842,35 +856,3 @@ interface JupyterTargetData {
842856
transient: boolean;
843857
kernelspec: JupyterKernelspec;
844858
}
845-
846-
export function executeResultIncludes(
847-
tempDir: string,
848-
widgetDependencies?: JupyterWidgetDependencies,
849-
): PandocIncludes | undefined {
850-
if (widgetDependencies) {
851-
const includes: PandocIncludes = {};
852-
const includeFiles = quarto.jupyter.widgetDependencyIncludes(
853-
[widgetDependencies],
854-
tempDir,
855-
);
856-
if (includeFiles.inHeader) {
857-
includes[kIncludeInHeader] = [includeFiles.inHeader];
858-
}
859-
if (includeFiles.afterBody) {
860-
includes[kIncludeAfterBody] = [includeFiles.afterBody];
861-
}
862-
return includes;
863-
} else {
864-
return undefined;
865-
}
866-
}
867-
868-
export function executeResultEngineDependencies(
869-
widgetDependencies?: JupyterWidgetDependencies,
870-
): Array<unknown> | undefined {
871-
if (widgetDependencies) {
872-
return [widgetDependencies];
873-
} else {
874-
return undefined;
875-
}
876-
}

0 commit comments

Comments
 (0)