diff --git a/src/cli.ts b/src/cli.ts index 4fa237d..a6d0444 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -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); @@ -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 }) diff --git a/src/index.ts b/src/index.ts index 7c215c4..c7ae385 100755 --- a/src/index.ts +++ b/src/index.ts @@ -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; @@ -50,9 +51,12 @@ export async function mdToPdf(input: Input, config: Partial = {}): 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; } diff --git a/src/lib/generate-output.ts b/src/lib/generate-output.ts index 366be0b..33bcbf8 100644 --- a/src/lib/generate-output.ts +++ b/src/lib/generate-output.ts @@ -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'; @@ -19,7 +19,7 @@ interface BasicOutput { /** * Store a single browser instance reference so that we can re-use it. */ -let browserPromise: Promise | undefined; +let browserPromise: Promise | undefined; /** * Close the browser instance. @@ -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; -export async function generateOutput(html: string, relativePath: string, config: HtmlConfig): Promise; -export async function generateOutput(html: string, relativePath: string, config: Config): Promise; -export async function generateOutput(html: string, relativePath: string, config: Config): Promise { - if (!browserPromise) { - browserPromise = puppeteer.launch({ devtools: config.devtools, ...config.launch_options }); +export async function generateOutput( + html: string, + relativePath: string, + config: PdfConfig, + browserRef?: Browser, +): Promise; +export async function generateOutput( + html: string, + relativePath: string, + config: HtmlConfig, + browserRef?: Browser, +): Promise; +export async function generateOutput( + html: string, + relativePath: string, + config: Config, + browserRef?: Browser, +): Promise; +export async function generateOutput( + html: string, + relativePath: string, + config: Config, + browserRef?: Browser, +): Promise { + 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(); diff --git a/src/lib/md-to-pdf.ts b/src/lib/md-to-pdf.ts index 62f993e..55cc9f2 100644 --- a/src/lib/md-to-pdf.ts +++ b/src/lib/md-to-pdf.ts @@ -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'; @@ -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 @@ -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) {