Skip to content

Commit 36fc51e

Browse files
committed
perf - reuse extension context to avoid traversing the file system multiple times
1 parent ae6bc34 commit 36fc51e

File tree

6 files changed

+39
-22
lines changed

6 files changed

+39
-22
lines changed

src/command/preview/cmd.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,11 @@ export const previewCommand = new Command()
391391
// see if we are serving a project or a file
392392
if (Deno.statSync(file).isDirectory) {
393393
// project preview
394-
await serveProject(projectTarget, flags, args, {
394+
const renderOptions = {
395+
services: renderServices(notebookContext()),
396+
flags,
397+
};
398+
await serveProject(projectTarget, renderOptions, args, {
395399
port: options.port,
396400
host: options.host,
397401
browser: (options.browser === false || options.browse === false)

src/command/render/project.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ export async function renderProject(
294294
context = await projectContextForDirectory(
295295
context.dir,
296296
context.notebookContext,
297-
projectRenderConfig.options.flags,
297+
projectRenderConfig.options,
298298
);
299299

300300
// Validate that certain project properties haven't been mutated

src/command/render/render-shared.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ import { renderProject } from "./project.ts";
1818
import { renderFiles } from "./render-files.ts";
1919
import { resourceFilesFromRenderedFile } from "./resources.ts";
2020
import { RenderFlags, RenderOptions, RenderResult } from "./types.ts";
21-
import {
22-
fileExecutionEngine,
23-
fileExecutionEngineAndTarget,
24-
} from "../../execute/engine.ts";
2521

2622
import {
2723
isProjectInputFile,
@@ -49,12 +45,12 @@ export async function render(
4945
const nbContext = notebookContext();
5046

5147
// determine target context/files
52-
let context = await projectContext(path, nbContext, options.flags);
48+
let context = await projectContext(path, nbContext, options);
5349

5450
// if there is no project parent and an output-dir was passed, then force a project
5551
if (!context && options.flags?.outputDir) {
5652
// recompute context
57-
context = await projectContextForDirectory(path, nbContext, options.flags);
53+
context = await projectContextForDirectory(path, nbContext, options);
5854

5955
// force clean as --output-dir implies fully overwrite the target
6056
options.forceClean = options.flags.clean !== false;

src/project/project-context.ts

+12-6
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ import {
6969
projectResolveFullMarkdownForFile,
7070
projectVarsFile,
7171
} from "./project-shared.ts";
72-
import { RenderFlags, RenderServices } from "../command/render/types.ts";
72+
import {
73+
RenderFlags,
74+
RenderOptions,
75+
RenderServices,
76+
} from "../command/render/types.ts";
7377
import { kWebsite } from "./types/website/website-constants.ts";
7478

7579
import { readAndValidateYamlFromFile } from "../core/schema/validated-yaml.ts";
@@ -95,16 +99,18 @@ import { MappedString } from "../core/mapped-text.ts";
9599
export async function projectContext(
96100
path: string,
97101
notebookContext: NotebookContext,
98-
flags?: RenderFlags,
102+
renderOptions?: RenderOptions,
99103
force = false,
100104
): Promise<ProjectContext | undefined> {
105+
const flags = renderOptions?.flags;
101106
let dir = normalizePath(
102107
Deno.statSync(path).isDirectory ? path : dirname(path),
103108
);
104109
const originalDir = dir;
105110

106-
// create a shared extension context
107-
const extensionContext = createExtensionContext();
111+
// create an extension context if one doesn't exist
112+
const extensionContext = renderOptions?.services.extension ||
113+
createExtensionContext();
108114

109115
// first pass uses the config file resolve
110116
const configSchema = await getProjectConfigSchema();
@@ -636,9 +642,9 @@ async function resolveLanguageTranslations(
636642
export function projectContextForDirectory(
637643
path: string,
638644
notebookContext: NotebookContext,
639-
flags?: RenderFlags,
645+
renderOptions?: RenderOptions,
640646
): Promise<ProjectContext> {
641-
return projectContext(path, notebookContext, flags, true) as Promise<
647+
return projectContext(path, notebookContext, renderOptions, true) as Promise<
642648
ProjectContext
643649
>;
644650
}

src/project/serve/serve.ts

+14-5
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ import { htmlResourceResolverPostprocessor } from "../../project/types/website/w
8282
import { inputFilesDir } from "../../core/render.ts";
8383
import { kResources, kTargetFormat } from "../../config/constants.ts";
8484
import { resourcesFromMetadata } from "../../command/render/resources.ts";
85-
import { RenderFlags, RenderResult } from "../../command/render/types.ts";
85+
import {
86+
RenderFlags,
87+
RenderOptions,
88+
RenderResult,
89+
} from "../../command/render/types.ts";
8690
import {
8791
kPdfJsInitialPath,
8892
pdfJsBaseDir,
@@ -124,18 +128,23 @@ export const kRenderDefault = "default";
124128

125129
export async function serveProject(
126130
target: string | ProjectContext,
127-
flags: RenderFlags,
131+
renderOptions: RenderOptions,
128132
pandocArgs: string[],
129133
options: ServeOptions,
130134
noServe: boolean,
131135
) {
132136
let project: ProjectContext | undefined;
133-
const nbContext = notebookContext();
137+
let flags = renderOptions.flags;
138+
const nbContext = renderOptions.services.notebook;
134139
if (typeof target === "string") {
135140
if (target === ".") {
136141
target = Deno.cwd();
137142
}
138-
project = await projectContext(target, nbContext, flags);
143+
project = await projectContext(
144+
target,
145+
nbContext,
146+
renderOptions,
147+
);
139148
if (!project || !project?.config) {
140149
throw new Error(`${target} is not a project`);
141150
}
@@ -301,7 +310,7 @@ export async function serveProject(
301310
project,
302311
extensionDirs,
303312
resourceFiles,
304-
flags,
313+
{ ...renderOptions, flags },
305314
pandocArgs,
306315
options,
307316
!pdfOutput, // we don't render on reload for pdf output

src/project/serve/watch.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { projectContext } from "../../project/project-context.ts";
2525

2626
import { ProjectWatcher, ServeOptions } from "./types.ts";
2727
import { httpDevServer } from "../../core/http-devserver.ts";
28-
import { RenderFlags } from "../../command/render/types.ts";
28+
import { RenderOptions } from "../../command/render/types.ts";
2929
import { renderProject } from "../../command/render/project.ts";
3030
import { render } from "../../command/render/render-shared.ts";
3131
import { renderServices } from "../../command/render/render-services.ts";
@@ -53,17 +53,19 @@ export function watchProject(
5353
project: ProjectContext,
5454
extensionDirs: string[],
5555
resourceFiles: string[],
56-
flags: RenderFlags,
56+
renderOptions: RenderOptions,
5757
pandocArgs: string[],
5858
options: ServeOptions,
5959
renderingOnReload: boolean,
6060
renderManager: ServeRenderManager,
6161
stopServer: VoidFunction,
6262
): Promise<ProjectWatcher> {
6363
const nbContext = notebookContext();
64+
const flags = renderOptions.flags;
6465
// helper to refresh project config
6566
const refreshProjectConfig = async () => {
66-
project = (await projectContext(project.dir, nbContext, flags, false))!;
67+
project =
68+
(await projectContext(project.dir, nbContext, renderOptions, false))!;
6769
};
6870

6971
// See if we're in draft mode

0 commit comments

Comments
 (0)