Skip to content

Commit

Permalink
fix: create one browser instance per programmatic API call
Browse files Browse the repository at this point in the history
Fixes #146.
  • Loading branch information
simonhaenisch committed Dec 18, 2022
1 parent 4a23079 commit eb86ef0
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 16 deletions.
4 changes: 2 additions & 2 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ async function main(args: typeof cliFlags, config: Config) {
*/

if (stdin) {
await convertMdToPdf({ content: stdin }, config, args)
await convertMdToPdf({ content: stdin }, config, { args })
.finally(async () => {
await closeBrowser();
await closeServer(server);
Expand All @@ -140,7 +140,7 @@ async function main(args: typeof cliFlags, config: Config) {

const getListrTask = (file: string) => ({
title: `generating ${args['--as-html'] ? 'HTML' : 'PDF'} from ${chalk.underline(file)}`,
task: async () => convertMdToPdf({ path: file }, config, args),
task: async () => convertMdToPdf({ path: file }, config, { args }),
});

await new Listr(files.map(getListrTask), { concurrent: true, exitOnError: false })
Expand Down
10 changes: 7 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#!/usr/bin/env node

import getPort from 'get-port';
import puppeteer from 'puppeteer';
import { Config, defaultConfig, HtmlConfig, PdfConfig } from './lib/config';
import { HtmlOutput, Output, PdfOutput } from './lib/generate-output';
import { getDir } from './lib/helpers';
import { convertMdToPdf } from './lib/md-to-pdf';
import { serveDirectory } from './lib/serve-dir';
import { closeServer, serveDirectory } from './lib/serve-dir';

type Input = ContentInput | PathInput;

Expand Down Expand Up @@ -50,9 +51,12 @@ export async function mdToPdf(input: Input, config: Partial<Config> = {}): Promi

const server = await serveDirectory(mergedConfig);

const pdf = await convertMdToPdf(input, mergedConfig);
const browser = await puppeteer.launch({ devtools: config.devtools, ...config.launch_options });

server.close();
const pdf = await convertMdToPdf(input, mergedConfig, { browser });

await browser.close();
await closeServer(server);

return pdf;
}
Expand Down
46 changes: 37 additions & 9 deletions src/lib/generate-output.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import puppeteer from 'puppeteer';
import puppeteer, { Browser } from 'puppeteer';
import { Config, HtmlConfig, PdfConfig } from './config';
import { isHttpUrl } from './is-http-url';

Expand All @@ -19,7 +19,7 @@ interface BasicOutput {
/**
* Store a single browser instance reference so that we can re-use it.
*/
let browserPromise: Promise<puppeteer.Browser> | undefined;
let browserPromise: Promise<Browser> | undefined;

/**
* Close the browser instance.
Expand All @@ -29,15 +29,43 @@ export const closeBrowser = async () => (await browserPromise)?.close();
/**
* Generate the output (either PDF or HTML).
*/
export async function generateOutput(html: string, relativePath: string, config: PdfConfig): Promise<PdfOutput>;
export async function generateOutput(html: string, relativePath: string, config: HtmlConfig): Promise<HtmlOutput>;
export async function generateOutput(html: string, relativePath: string, config: Config): Promise<Output>;
export async function generateOutput(html: string, relativePath: string, config: Config): Promise<Output> {
if (!browserPromise) {
browserPromise = puppeteer.launch({ devtools: config.devtools, ...config.launch_options });
export async function generateOutput(
html: string,
relativePath: string,
config: PdfConfig,
browserRef?: Browser,
): Promise<PdfOutput>;
export async function generateOutput(
html: string,
relativePath: string,
config: HtmlConfig,
browserRef?: Browser,
): Promise<HtmlOutput>;
export async function generateOutput(
html: string,
relativePath: string,
config: Config,
browserRef?: Browser,
): Promise<Output>;
export async function generateOutput(
html: string,
relativePath: string,
config: Config,
browserRef?: Browser,
): Promise<Output> {
async function getBrowser() {
if (browserRef) {
return browserRef;
}

if (!browserPromise) {
browserPromise = puppeteer.launch({ devtools: config.devtools, ...config.launch_options });
}

return browserPromise;
}

const browser = await browserPromise;
const browser = await getBrowser();

const page = await browser.newPage();

Expand Down
11 changes: 9 additions & 2 deletions src/lib/md-to-pdf.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { promises as fs } from 'fs';
import grayMatter from 'gray-matter';
import { dirname, resolve } from 'path';
import { Browser } from 'puppeteer';
import { Config } from './config';
import { generateOutput } from './generate-output';
import { getHtml } from './get-html';
Expand All @@ -16,7 +17,13 @@ type CliArgs = typeof import('../cli').cliFlags;
export const convertMdToPdf = async (
input: { path: string } | { content: string },
config: Config,
args: CliArgs = {} as CliArgs,
{
args = {} as CliArgs,
browser,
}: {
args?: CliArgs;
browser?: Browser;
} = {},
) => {
const mdFileContent =
'content' in input
Expand Down Expand Up @@ -87,7 +94,7 @@ export const convertMdToPdf = async (

const relativePath = 'path' in input ? resolve(input.path).replace(config.basedir, '') : '/';

const output = await generateOutput(html, relativePath, config);
const output = await generateOutput(html, relativePath, config, browser);

if (!output) {
if (config.devtools) {
Expand Down

0 comments on commit eb86ef0

Please sign in to comment.