kandi background
Explore Kits

lerna | managing JavaScript projects with multiple packages | Blockchain library

 by   lerna JavaScript Version: v4.0.0 License: MIT

 by   lerna JavaScript Version: v4.0.0 License: MIT

Download this library from

kandi X-RAY | lerna Summary

lerna is a JavaScript library typically used in Blockchain applications. lerna has no bugs, it has no vulnerabilities, it has a Permissive License and it has medium support. You can install using 'npm i douglasduteil...lerna' or download it from GitHub, npm.
Splitting up large codebases into separate independently versioned packages is extremely useful for code sharing. However, making changes across many repositories is messy and difficult to track, and testing across repositories becomes complicated very quickly. To solve these (and many other) problems, some projects will organize their codebases into multi-package repositories (sometimes called monorepos). Projects like Babel, React, Angular, Ember, Meteor, Jest, and many others develop all of their packages within a single repository. Lerna can also reduce the time and space requirements for numerous copies of packages in development and build environments - normally a downside of dividing a project into many separate NPM packages. See the hoist documentation for details.
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • lerna has a medium active ecosystem.
  • It has 31453 star(s) with 2066 fork(s). There are 254 watchers for this library.
  • It had no major release in the last 12 months.
  • There are 687 open issues and 1487 have been closed. On average issues are closed in 102 days. There are 66 open pull requests and 0 closed requests.
  • It has a neutral sentiment in the developer community.
  • The latest version of lerna is v4.0.0
lerna Support
Best in #Blockchain
Average in #Blockchain
lerna Support
Best in #Blockchain
Average in #Blockchain

quality kandi Quality

  • lerna has 0 bugs and 0 code smells.
lerna Quality
Best in #Blockchain
Average in #Blockchain
lerna Quality
Best in #Blockchain
Average in #Blockchain

securitySecurity

  • lerna has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • lerna code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.
lerna Security
Best in #Blockchain
Average in #Blockchain
lerna Security
Best in #Blockchain
Average in #Blockchain

license License

  • lerna is licensed under the MIT License. This license is Permissive.
  • Permissive licenses have the least restrictions, and you can use them in most projects.
lerna License
Best in #Blockchain
Average in #Blockchain
lerna License
Best in #Blockchain
Average in #Blockchain

buildReuse

  • lerna releases are available to install and integrate.
  • Deployable package is available in npm.
  • Installation instructions, examples and code snippets are available.
lerna Reuse
Best in #Blockchain
Average in #Blockchain
lerna Reuse
Best in #Blockchain
Average in #Blockchain
Top functions reviewed by kandi - BETA

kandi has reviewed lerna and discovered the below as its top functions. This is intended to give you an instant insight into lerna implemented functionality, and help decide if they suit your requirements.

  • Run lifecycle .
  • Create the filter options .
  • Adds a version to the changelog .
  • Gets the changelog config .
  • Collect the updates from the git repo .
  • Build the graph
  • Create a symlink for the specified packages .
  • Higher order function to create a dependency matchers
  • Log the tarball
  • Maps a name to the registry

lerna Key Features

:dragon: A tool for managing JavaScript projects with multiple packages.

What does a Lerna repo look like?

copy iconCopydownload iconDownload
my-lerna-repo/
  package.json
  packages/
    package-1/
      package.json
    package-2/
      package.json

Getting Started

copy iconCopydownload iconDownload
$ mkdir lerna-repo && cd $_
$ npx lerna init

lerna.json

copy iconCopydownload iconDownload
{
  "version": "1.1.3",
  "npmClient": "npm",
  "command": {
    "publish": {
      "ignoreChanges": ["ignored-file", "*.md"],
      "message": "chore(release): publish",
      "registry": "https://npm.pkg.github.com"
    },
    "bootstrap": {
      "ignore": "component-*",
      "npmClientArgs": ["--no-package-lock"]
    }
  },
  "packages": ["packages/*"]
}

Common

copy iconCopydownload iconDownload
{
  "scripts": {
    "nsp": "nsp"
  },
  "devDependencies": {
    "nsp": "^2.3.3"
  }
}

Git Hosted Dependencies

copy iconCopydownload iconDownload
// packages/pkg-1/package.json
{
  name: "pkg-1",
  version: "1.0.0",
  dependencies: {
    "pkg-2": "github:example-user/pkg-2#v1.0.0"
  }
}

// packages/pkg-2/package.json
{
  name: "pkg-2",
  version: "1.0.0"
}

README Badge

copy iconCopydownload iconDownload
[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)

How to filter NPM commands to a pattern of workspaces (like filter, include, exclude, glob, grep or subdirectory)?

copy iconCopydownload iconDownload
npm run --workspace packages/presets --workspace packages/plugins build
npm run --workspace packages/** build
  "workspaces": [
    "packages/plugins/*",
    "packages/presets/*",
    ...more
  ],
  "workspaces": [
    "packages/**",
    ...more
  ],
-----------------------
npm run --workspace packages/presets --workspace packages/plugins build
npm run --workspace packages/** build
  "workspaces": [
    "packages/plugins/*",
    "packages/presets/*",
    ...more
  ],
  "workspaces": [
    "packages/**",
    ...more
  ],
-----------------------
npm run --workspace packages/presets --workspace packages/plugins build
npm run --workspace packages/** build
  "workspaces": [
    "packages/plugins/*",
    "packages/presets/*",
    ...more
  ],
  "workspaces": [
    "packages/**",
    ...more
  ],
-----------------------
npm run --workspace packages/presets --workspace packages/plugins build
npm run --workspace packages/** build
  "workspaces": [
    "packages/plugins/*",
    "packages/presets/*",
    ...more
  ],
  "workspaces": [
    "packages/**",
    ...more
  ],
-----------------------
npm run <script-name> --workspace parent/directory/
npm publish --workspace packages/public/
npm run build --workspace packages/helpers/
Valid values for the workspace config are either:

Workspace names
Path to a workspace directory
Path to a parent workspace directory (will result in selecting all workspaces within that folder)
-----------------------
npm run <script-name> --workspace parent/directory/
npm publish --workspace packages/public/
npm run build --workspace packages/helpers/
Valid values for the workspace config are either:

Workspace names
Path to a workspace directory
Path to a parent workspace directory (will result in selecting all workspaces within that folder)
-----------------------
npm run <script-name> --workspace parent/directory/
npm publish --workspace packages/public/
npm run build --workspace packages/helpers/
Valid values for the workspace config are either:

Workspace names
Path to a workspace directory
Path to a parent workspace directory (will result in selecting all workspaces within that folder)

Puppeteer create PDF files from HTML data hangs Windows 10 system

copy iconCopydownload iconDownload

var puppeteer = require('puppeteer')

const defaultPrinterOptions = {
    format: 'A4',
    printBackground: true,
    margin: {
        left: '0px',
        top: '0px',
        right: '0px',
        bottom: '0px'
    }
}

class PdfPrinter {

    maxBrowsers = 2
    enqueuedPrintJobs = []
    failedJobs = []
    browserInstances = 0

    // max browser instances in parallel 
    constructor(maxBrowsers) {
        this.maxBrowsers = maxBrowsers
    }

    /**
     * 
     * @param {*} html the html content to print
     * @param {*} css to apply to the page
     * @param {*} printOptions options passed to puppeteer
     */
    // enqueues a print but the exact end moment cannot be known..
    enqueuePrint = (html, css, path, done) => {
        // merge custom options with defaultOptions..
        const printOptions = {
            ...defaultPrinterOptions,

            // add the path to the options.
            path: path
        }

        // create a function which can be stored in an array
        // it will later be grabbed by startPrinter() OR at the time any 
        // brwoser freed up.. 
        // the function needs to be passed the actual used browser instance!
        this.enqueuedPrintJobs.push(async(browser) => {

            // catch the error which may be produced when printing something..
            try {
                // print the document
                await this.print(browser, html, css, printOptions)
            } catch (err) {
                console.error('error when printing document..CLosing browser and starting a new job!!', printOptions.path)
                console.error(err)

                // store someting so you now what failed and coudl be retried or something..
                this.failedJobs.push({ html, css, path: printOptions.path })

                // puppeteer can run into erros too!! 
                // so close the browser and launch a new one!
                await this.closeBrowser(browser)
                browser = await this.launchBrowser()
            }

            // after the print, call done() so the promise is resovled in the right moment when 
            // this particular print has ended.!
            done()

            // start the next job right now  if there are any left.
            const job = this.enqueuedPrintJobs.shift()

            if (!job) {
                console.log('No print jobs available anymore. CLosing this browser instance.. Remaining browsers now:', this.maxBrowsers - this.browserInstances + 1)
                await this.closeBrowser(browser)
                return
            }

            // job is actually this function itself! It will be executed
            // and automatically grab a new job after completion :)
            // we pass the same browser instance to the next job!.
            await job(browser)
        })

        // whenever a print job added make sure to start the printer
        // this starts new browser instances if the limit is not exceeded resp. if no browser is instantiated yet,
        // and does nothing if maximum browser count is reached..
        this.tryStartPrinter()
    }

    // same as enqueuePrint except it wraps it in a promise so we can now the
    // exact end moment and await it..
    enqueuePrintPromise(html, css, path) {
        return new Promise((resolve, reject) => {
            try {
                this.enqueuePrint(html, css, path, resolve)
            } catch (err) {
                console.error('unexpected error when setting up print job..', err)
                reject(err)
            }
        })

    }

    // If browser instance limit is not reached will isntantiate a new one and run a print job with it.
    // a print job will automatically grab a next job with the created browser if there are any left.
    tryStartPrinter = async() => {

        // Max browser count in use OR no jobs left.
        if (this.browserInstances >= this.maxBrowsers || this.enqueuedPrintJobs.length === 0) {
            return
        }
        // browser instances available! 
        // create a new one 

        console.log('launching new browser. Available after launch:', this.maxBrowsers - this.browserInstances - 1)
        const browser = await this.launchBrowser()
        
        // run job
        const job = this.enqueuedPrintJobs.shift()
        await job(browser)

    }

    closeBrowser = async(browser) => {


        // decrement browsers in use!
        // important to call before closing browser!!
        this.browserInstances--
        await browser.close()

    }

    launchBrowser = async() => {
        // increment browsers in use!
        // important to increase before actualy launching (async stuff..)
        this.browserInstances++

        // this code you have to adjust according your enviromnemt..
        const browser = await puppeteer.launch({ headless: true })

        return browser
    }


    // The actual print function which creates a pdf.
    print = async(browser, html, css, printOptions) => {

        console.log('Converting page to pdf. path:', printOptions.path)
            // Run pdf creation in seperate page.
        const page = await browser.newPage()

        await page.setContent(html, { waitUntil: 'networkidle0' });
        await page.addStyleTag({ content: css });
        await page.pdf(printOptions);
        await page.close();

    }

}

// testing the PDFPrinter with some jobs.
// make sure to run the printer in an `async` function so u can 
// use await... 
const testPrinterQueue = async() => {

    // config
    const maxOpenedBrowsers = 5 // amount of browser instances which are allowed to be opened in parallel
    const testJobCount = 100 // amount of test pdf jobs to be created
    const destDir = 'C:\\somepath' // the directory to store the pdfs in..


    // create sample jobs for testing...
    const jobs = []
    for (let i = 0; i < testJobCount; i++) {
        jobs.push({
            html: `<h1>job number [${i}]</h1>`,
            css: 'h1 { background-color: red; }',
            path: require('path').join(destDir, `pdf_${i}.pdf`)
        })
    }

    // track time
    const label = 'printed a total of ' + testJobCount + ' pdfs!'
    console.time(label)

    // run the actual pdf generation..
    const printer = new PdfPrinter(maxOpenedBrowsers)

    const jobProms = []
    for (let job of jobs) {

        // run jobs in parallel. Each job wil be runned async and return a Promise therefor
        jobProms.push(
            printer.enqueuePrintPromise(job.html, job.css, job.path)
        )
    }

    console.log('All jobs enqueued!! Wating for finish now.')

    // helper function which awaits all the print jobs, resp. an array of promises.
    await Promise.all(jobProms)
    console.timeEnd(label)

    // failed jobs::
    console.log('jobs failed:', printer.failedJobs)

    // as file:
    await require('fs').promises.writeFile('failed-jobs.json', JSON.stringify(printer.failedJobs))
}


testPrinterQueue().then(() => {
    console.log('done with everyting..')
}).catch(err => {
    console.error('unexpected error occured while printing all pages...', err)
})
(async () => {
        browser = await Puppeteer.launch({
            headless: true,
            handleSIGINT: false,
            args: args,
        });

        const page = await browser.newPage();
    
        await page.setViewport({
            width: resolution.x,
            height: resolution.y,
        })

        await computeFirstTerm(page);
        await computeSecondTerm(page);
        await computeThirdTerm(page);
        browser.close()
    })()

//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};


function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    AsyncFunction();

    // what you have done in your code:
    (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction()
console.log('done')

Async named function started
Async anonymus function started
sync function ended. // => sync function already ended 
done   // sync function ended and code continues execution.
Async named function ended
Async anonymus function ended
//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};

// this is now async!!
async function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    await AsyncFunction();

    // what you have done in your code:
    await (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction().then(() => {
    console.log('done')
}).catch(err => {
    console.error('unexpected error occured..')
})

sync function started
Async named function started
Async named function ended
Async anonymus function started
Async anonymus function ended
sync function ended.
done

-----------------------

var puppeteer = require('puppeteer')

const defaultPrinterOptions = {
    format: 'A4',
    printBackground: true,
    margin: {
        left: '0px',
        top: '0px',
        right: '0px',
        bottom: '0px'
    }
}

class PdfPrinter {

    maxBrowsers = 2
    enqueuedPrintJobs = []
    failedJobs = []
    browserInstances = 0

    // max browser instances in parallel 
    constructor(maxBrowsers) {
        this.maxBrowsers = maxBrowsers
    }

    /**
     * 
     * @param {*} html the html content to print
     * @param {*} css to apply to the page
     * @param {*} printOptions options passed to puppeteer
     */
    // enqueues a print but the exact end moment cannot be known..
    enqueuePrint = (html, css, path, done) => {
        // merge custom options with defaultOptions..
        const printOptions = {
            ...defaultPrinterOptions,

            // add the path to the options.
            path: path
        }

        // create a function which can be stored in an array
        // it will later be grabbed by startPrinter() OR at the time any 
        // brwoser freed up.. 
        // the function needs to be passed the actual used browser instance!
        this.enqueuedPrintJobs.push(async(browser) => {

            // catch the error which may be produced when printing something..
            try {
                // print the document
                await this.print(browser, html, css, printOptions)
            } catch (err) {
                console.error('error when printing document..CLosing browser and starting a new job!!', printOptions.path)
                console.error(err)

                // store someting so you now what failed and coudl be retried or something..
                this.failedJobs.push({ html, css, path: printOptions.path })

                // puppeteer can run into erros too!! 
                // so close the browser and launch a new one!
                await this.closeBrowser(browser)
                browser = await this.launchBrowser()
            }

            // after the print, call done() so the promise is resovled in the right moment when 
            // this particular print has ended.!
            done()

            // start the next job right now  if there are any left.
            const job = this.enqueuedPrintJobs.shift()

            if (!job) {
                console.log('No print jobs available anymore. CLosing this browser instance.. Remaining browsers now:', this.maxBrowsers - this.browserInstances + 1)
                await this.closeBrowser(browser)
                return
            }

            // job is actually this function itself! It will be executed
            // and automatically grab a new job after completion :)
            // we pass the same browser instance to the next job!.
            await job(browser)
        })

        // whenever a print job added make sure to start the printer
        // this starts new browser instances if the limit is not exceeded resp. if no browser is instantiated yet,
        // and does nothing if maximum browser count is reached..
        this.tryStartPrinter()
    }

    // same as enqueuePrint except it wraps it in a promise so we can now the
    // exact end moment and await it..
    enqueuePrintPromise(html, css, path) {
        return new Promise((resolve, reject) => {
            try {
                this.enqueuePrint(html, css, path, resolve)
            } catch (err) {
                console.error('unexpected error when setting up print job..', err)
                reject(err)
            }
        })

    }

    // If browser instance limit is not reached will isntantiate a new one and run a print job with it.
    // a print job will automatically grab a next job with the created browser if there are any left.
    tryStartPrinter = async() => {

        // Max browser count in use OR no jobs left.
        if (this.browserInstances >= this.maxBrowsers || this.enqueuedPrintJobs.length === 0) {
            return
        }
        // browser instances available! 
        // create a new one 

        console.log('launching new browser. Available after launch:', this.maxBrowsers - this.browserInstances - 1)
        const browser = await this.launchBrowser()
        
        // run job
        const job = this.enqueuedPrintJobs.shift()
        await job(browser)

    }

    closeBrowser = async(browser) => {


        // decrement browsers in use!
        // important to call before closing browser!!
        this.browserInstances--
        await browser.close()

    }

    launchBrowser = async() => {
        // increment browsers in use!
        // important to increase before actualy launching (async stuff..)
        this.browserInstances++

        // this code you have to adjust according your enviromnemt..
        const browser = await puppeteer.launch({ headless: true })

        return browser
    }


    // The actual print function which creates a pdf.
    print = async(browser, html, css, printOptions) => {

        console.log('Converting page to pdf. path:', printOptions.path)
            // Run pdf creation in seperate page.
        const page = await browser.newPage()

        await page.setContent(html, { waitUntil: 'networkidle0' });
        await page.addStyleTag({ content: css });
        await page.pdf(printOptions);
        await page.close();

    }

}

// testing the PDFPrinter with some jobs.
// make sure to run the printer in an `async` function so u can 
// use await... 
const testPrinterQueue = async() => {

    // config
    const maxOpenedBrowsers = 5 // amount of browser instances which are allowed to be opened in parallel
    const testJobCount = 100 // amount of test pdf jobs to be created
    const destDir = 'C:\\somepath' // the directory to store the pdfs in..


    // create sample jobs for testing...
    const jobs = []
    for (let i = 0; i < testJobCount; i++) {
        jobs.push({
            html: `<h1>job number [${i}]</h1>`,
            css: 'h1 { background-color: red; }',
            path: require('path').join(destDir, `pdf_${i}.pdf`)
        })
    }

    // track time
    const label = 'printed a total of ' + testJobCount + ' pdfs!'
    console.time(label)

    // run the actual pdf generation..
    const printer = new PdfPrinter(maxOpenedBrowsers)

    const jobProms = []
    for (let job of jobs) {

        // run jobs in parallel. Each job wil be runned async and return a Promise therefor
        jobProms.push(
            printer.enqueuePrintPromise(job.html, job.css, job.path)
        )
    }

    console.log('All jobs enqueued!! Wating for finish now.')

    // helper function which awaits all the print jobs, resp. an array of promises.
    await Promise.all(jobProms)
    console.timeEnd(label)

    // failed jobs::
    console.log('jobs failed:', printer.failedJobs)

    // as file:
    await require('fs').promises.writeFile('failed-jobs.json', JSON.stringify(printer.failedJobs))
}


testPrinterQueue().then(() => {
    console.log('done with everyting..')
}).catch(err => {
    console.error('unexpected error occured while printing all pages...', err)
})
(async () => {
        browser = await Puppeteer.launch({
            headless: true,
            handleSIGINT: false,
            args: args,
        });

        const page = await browser.newPage();
    
        await page.setViewport({
            width: resolution.x,
            height: resolution.y,
        })

        await computeFirstTerm(page);
        await computeSecondTerm(page);
        await computeThirdTerm(page);
        browser.close()
    })()

//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};


function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    AsyncFunction();

    // what you have done in your code:
    (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction()
console.log('done')

Async named function started
Async anonymus function started
sync function ended. // => sync function already ended 
done   // sync function ended and code continues execution.
Async named function ended
Async anonymus function ended
//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};

// this is now async!!
async function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    await AsyncFunction();

    // what you have done in your code:
    await (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction().then(() => {
    console.log('done')
}).catch(err => {
    console.error('unexpected error occured..')
})

sync function started
Async named function started
Async named function ended
Async anonymus function started
Async anonymus function ended
sync function ended.
done

-----------------------

var puppeteer = require('puppeteer')

const defaultPrinterOptions = {
    format: 'A4',
    printBackground: true,
    margin: {
        left: '0px',
        top: '0px',
        right: '0px',
        bottom: '0px'
    }
}

class PdfPrinter {

    maxBrowsers = 2
    enqueuedPrintJobs = []
    failedJobs = []
    browserInstances = 0

    // max browser instances in parallel 
    constructor(maxBrowsers) {
        this.maxBrowsers = maxBrowsers
    }

    /**
     * 
     * @param {*} html the html content to print
     * @param {*} css to apply to the page
     * @param {*} printOptions options passed to puppeteer
     */
    // enqueues a print but the exact end moment cannot be known..
    enqueuePrint = (html, css, path, done) => {
        // merge custom options with defaultOptions..
        const printOptions = {
            ...defaultPrinterOptions,

            // add the path to the options.
            path: path
        }

        // create a function which can be stored in an array
        // it will later be grabbed by startPrinter() OR at the time any 
        // brwoser freed up.. 
        // the function needs to be passed the actual used browser instance!
        this.enqueuedPrintJobs.push(async(browser) => {

            // catch the error which may be produced when printing something..
            try {
                // print the document
                await this.print(browser, html, css, printOptions)
            } catch (err) {
                console.error('error when printing document..CLosing browser and starting a new job!!', printOptions.path)
                console.error(err)

                // store someting so you now what failed and coudl be retried or something..
                this.failedJobs.push({ html, css, path: printOptions.path })

                // puppeteer can run into erros too!! 
                // so close the browser and launch a new one!
                await this.closeBrowser(browser)
                browser = await this.launchBrowser()
            }

            // after the print, call done() so the promise is resovled in the right moment when 
            // this particular print has ended.!
            done()

            // start the next job right now  if there are any left.
            const job = this.enqueuedPrintJobs.shift()

            if (!job) {
                console.log('No print jobs available anymore. CLosing this browser instance.. Remaining browsers now:', this.maxBrowsers - this.browserInstances + 1)
                await this.closeBrowser(browser)
                return
            }

            // job is actually this function itself! It will be executed
            // and automatically grab a new job after completion :)
            // we pass the same browser instance to the next job!.
            await job(browser)
        })

        // whenever a print job added make sure to start the printer
        // this starts new browser instances if the limit is not exceeded resp. if no browser is instantiated yet,
        // and does nothing if maximum browser count is reached..
        this.tryStartPrinter()
    }

    // same as enqueuePrint except it wraps it in a promise so we can now the
    // exact end moment and await it..
    enqueuePrintPromise(html, css, path) {
        return new Promise((resolve, reject) => {
            try {
                this.enqueuePrint(html, css, path, resolve)
            } catch (err) {
                console.error('unexpected error when setting up print job..', err)
                reject(err)
            }
        })

    }

    // If browser instance limit is not reached will isntantiate a new one and run a print job with it.
    // a print job will automatically grab a next job with the created browser if there are any left.
    tryStartPrinter = async() => {

        // Max browser count in use OR no jobs left.
        if (this.browserInstances >= this.maxBrowsers || this.enqueuedPrintJobs.length === 0) {
            return
        }
        // browser instances available! 
        // create a new one 

        console.log('launching new browser. Available after launch:', this.maxBrowsers - this.browserInstances - 1)
        const browser = await this.launchBrowser()
        
        // run job
        const job = this.enqueuedPrintJobs.shift()
        await job(browser)

    }

    closeBrowser = async(browser) => {


        // decrement browsers in use!
        // important to call before closing browser!!
        this.browserInstances--
        await browser.close()

    }

    launchBrowser = async() => {
        // increment browsers in use!
        // important to increase before actualy launching (async stuff..)
        this.browserInstances++

        // this code you have to adjust according your enviromnemt..
        const browser = await puppeteer.launch({ headless: true })

        return browser
    }


    // The actual print function which creates a pdf.
    print = async(browser, html, css, printOptions) => {

        console.log('Converting page to pdf. path:', printOptions.path)
            // Run pdf creation in seperate page.
        const page = await browser.newPage()

        await page.setContent(html, { waitUntil: 'networkidle0' });
        await page.addStyleTag({ content: css });
        await page.pdf(printOptions);
        await page.close();

    }

}

// testing the PDFPrinter with some jobs.
// make sure to run the printer in an `async` function so u can 
// use await... 
const testPrinterQueue = async() => {

    // config
    const maxOpenedBrowsers = 5 // amount of browser instances which are allowed to be opened in parallel
    const testJobCount = 100 // amount of test pdf jobs to be created
    const destDir = 'C:\\somepath' // the directory to store the pdfs in..


    // create sample jobs for testing...
    const jobs = []
    for (let i = 0; i < testJobCount; i++) {
        jobs.push({
            html: `<h1>job number [${i}]</h1>`,
            css: 'h1 { background-color: red; }',
            path: require('path').join(destDir, `pdf_${i}.pdf`)
        })
    }

    // track time
    const label = 'printed a total of ' + testJobCount + ' pdfs!'
    console.time(label)

    // run the actual pdf generation..
    const printer = new PdfPrinter(maxOpenedBrowsers)

    const jobProms = []
    for (let job of jobs) {

        // run jobs in parallel. Each job wil be runned async and return a Promise therefor
        jobProms.push(
            printer.enqueuePrintPromise(job.html, job.css, job.path)
        )
    }

    console.log('All jobs enqueued!! Wating for finish now.')

    // helper function which awaits all the print jobs, resp. an array of promises.
    await Promise.all(jobProms)
    console.timeEnd(label)

    // failed jobs::
    console.log('jobs failed:', printer.failedJobs)

    // as file:
    await require('fs').promises.writeFile('failed-jobs.json', JSON.stringify(printer.failedJobs))
}


testPrinterQueue().then(() => {
    console.log('done with everyting..')
}).catch(err => {
    console.error('unexpected error occured while printing all pages...', err)
})
(async () => {
        browser = await Puppeteer.launch({
            headless: true,
            handleSIGINT: false,
            args: args,
        });

        const page = await browser.newPage();
    
        await page.setViewport({
            width: resolution.x,
            height: resolution.y,
        })

        await computeFirstTerm(page);
        await computeSecondTerm(page);
        await computeThirdTerm(page);
        browser.close()
    })()

//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};


function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    AsyncFunction();

    // what you have done in your code:
    (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction()
console.log('done')

Async named function started
Async anonymus function started
sync function ended. // => sync function already ended 
done   // sync function ended and code continues execution.
Async named function ended
Async anonymus function ended
//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};

// this is now async!!
async function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    await AsyncFunction();

    // what you have done in your code:
    await (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction().then(() => {
    console.log('done')
}).catch(err => {
    console.error('unexpected error occured..')
})

sync function started
Async named function started
Async named function ended
Async anonymus function started
Async anonymus function ended
sync function ended.
done

-----------------------

var puppeteer = require('puppeteer')

const defaultPrinterOptions = {
    format: 'A4',
    printBackground: true,
    margin: {
        left: '0px',
        top: '0px',
        right: '0px',
        bottom: '0px'
    }
}

class PdfPrinter {

    maxBrowsers = 2
    enqueuedPrintJobs = []
    failedJobs = []
    browserInstances = 0

    // max browser instances in parallel 
    constructor(maxBrowsers) {
        this.maxBrowsers = maxBrowsers
    }

    /**
     * 
     * @param {*} html the html content to print
     * @param {*} css to apply to the page
     * @param {*} printOptions options passed to puppeteer
     */
    // enqueues a print but the exact end moment cannot be known..
    enqueuePrint = (html, css, path, done) => {
        // merge custom options with defaultOptions..
        const printOptions = {
            ...defaultPrinterOptions,

            // add the path to the options.
            path: path
        }

        // create a function which can be stored in an array
        // it will later be grabbed by startPrinter() OR at the time any 
        // brwoser freed up.. 
        // the function needs to be passed the actual used browser instance!
        this.enqueuedPrintJobs.push(async(browser) => {

            // catch the error which may be produced when printing something..
            try {
                // print the document
                await this.print(browser, html, css, printOptions)
            } catch (err) {
                console.error('error when printing document..CLosing browser and starting a new job!!', printOptions.path)
                console.error(err)

                // store someting so you now what failed and coudl be retried or something..
                this.failedJobs.push({ html, css, path: printOptions.path })

                // puppeteer can run into erros too!! 
                // so close the browser and launch a new one!
                await this.closeBrowser(browser)
                browser = await this.launchBrowser()
            }

            // after the print, call done() so the promise is resovled in the right moment when 
            // this particular print has ended.!
            done()

            // start the next job right now  if there are any left.
            const job = this.enqueuedPrintJobs.shift()

            if (!job) {
                console.log('No print jobs available anymore. CLosing this browser instance.. Remaining browsers now:', this.maxBrowsers - this.browserInstances + 1)
                await this.closeBrowser(browser)
                return
            }

            // job is actually this function itself! It will be executed
            // and automatically grab a new job after completion :)
            // we pass the same browser instance to the next job!.
            await job(browser)
        })

        // whenever a print job added make sure to start the printer
        // this starts new browser instances if the limit is not exceeded resp. if no browser is instantiated yet,
        // and does nothing if maximum browser count is reached..
        this.tryStartPrinter()
    }

    // same as enqueuePrint except it wraps it in a promise so we can now the
    // exact end moment and await it..
    enqueuePrintPromise(html, css, path) {
        return new Promise((resolve, reject) => {
            try {
                this.enqueuePrint(html, css, path, resolve)
            } catch (err) {
                console.error('unexpected error when setting up print job..', err)
                reject(err)
            }
        })

    }

    // If browser instance limit is not reached will isntantiate a new one and run a print job with it.
    // a print job will automatically grab a next job with the created browser if there are any left.
    tryStartPrinter = async() => {

        // Max browser count in use OR no jobs left.
        if (this.browserInstances >= this.maxBrowsers || this.enqueuedPrintJobs.length === 0) {
            return
        }
        // browser instances available! 
        // create a new one 

        console.log('launching new browser. Available after launch:', this.maxBrowsers - this.browserInstances - 1)
        const browser = await this.launchBrowser()
        
        // run job
        const job = this.enqueuedPrintJobs.shift()
        await job(browser)

    }

    closeBrowser = async(browser) => {


        // decrement browsers in use!
        // important to call before closing browser!!
        this.browserInstances--
        await browser.close()

    }

    launchBrowser = async() => {
        // increment browsers in use!
        // important to increase before actualy launching (async stuff..)
        this.browserInstances++

        // this code you have to adjust according your enviromnemt..
        const browser = await puppeteer.launch({ headless: true })

        return browser
    }


    // The actual print function which creates a pdf.
    print = async(browser, html, css, printOptions) => {

        console.log('Converting page to pdf. path:', printOptions.path)
            // Run pdf creation in seperate page.
        const page = await browser.newPage()

        await page.setContent(html, { waitUntil: 'networkidle0' });
        await page.addStyleTag({ content: css });
        await page.pdf(printOptions);
        await page.close();

    }

}

// testing the PDFPrinter with some jobs.
// make sure to run the printer in an `async` function so u can 
// use await... 
const testPrinterQueue = async() => {

    // config
    const maxOpenedBrowsers = 5 // amount of browser instances which are allowed to be opened in parallel
    const testJobCount = 100 // amount of test pdf jobs to be created
    const destDir = 'C:\\somepath' // the directory to store the pdfs in..


    // create sample jobs for testing...
    const jobs = []
    for (let i = 0; i < testJobCount; i++) {
        jobs.push({
            html: `<h1>job number [${i}]</h1>`,
            css: 'h1 { background-color: red; }',
            path: require('path').join(destDir, `pdf_${i}.pdf`)
        })
    }

    // track time
    const label = 'printed a total of ' + testJobCount + ' pdfs!'
    console.time(label)

    // run the actual pdf generation..
    const printer = new PdfPrinter(maxOpenedBrowsers)

    const jobProms = []
    for (let job of jobs) {

        // run jobs in parallel. Each job wil be runned async and return a Promise therefor
        jobProms.push(
            printer.enqueuePrintPromise(job.html, job.css, job.path)
        )
    }

    console.log('All jobs enqueued!! Wating for finish now.')

    // helper function which awaits all the print jobs, resp. an array of promises.
    await Promise.all(jobProms)
    console.timeEnd(label)

    // failed jobs::
    console.log('jobs failed:', printer.failedJobs)

    // as file:
    await require('fs').promises.writeFile('failed-jobs.json', JSON.stringify(printer.failedJobs))
}


testPrinterQueue().then(() => {
    console.log('done with everyting..')
}).catch(err => {
    console.error('unexpected error occured while printing all pages...', err)
})
(async () => {
        browser = await Puppeteer.launch({
            headless: true,
            handleSIGINT: false,
            args: args,
        });

        const page = await browser.newPage();
    
        await page.setViewport({
            width: resolution.x,
            height: resolution.y,
        })

        await computeFirstTerm(page);
        await computeSecondTerm(page);
        await computeThirdTerm(page);
        browser.close()
    })()

//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};


function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    AsyncFunction();

    // what you have done in your code:
    (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction()
console.log('done')

Async named function started
Async anonymus function started
sync function ended. // => sync function already ended 
done   // sync function ended and code continues execution.
Async named function ended
Async anonymus function ended
//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};

// this is now async!!
async function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    await AsyncFunction();

    // what you have done in your code:
    await (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction().then(() => {
    console.log('done')
}).catch(err => {
    console.error('unexpected error occured..')
})

sync function started
Async named function started
Async named function ended
Async anonymus function started
Async anonymus function ended
sync function ended.
done

-----------------------

var puppeteer = require('puppeteer')

const defaultPrinterOptions = {
    format: 'A4',
    printBackground: true,
    margin: {
        left: '0px',
        top: '0px',
        right: '0px',
        bottom: '0px'
    }
}

class PdfPrinter {

    maxBrowsers = 2
    enqueuedPrintJobs = []
    failedJobs = []
    browserInstances = 0

    // max browser instances in parallel 
    constructor(maxBrowsers) {
        this.maxBrowsers = maxBrowsers
    }

    /**
     * 
     * @param {*} html the html content to print
     * @param {*} css to apply to the page
     * @param {*} printOptions options passed to puppeteer
     */
    // enqueues a print but the exact end moment cannot be known..
    enqueuePrint = (html, css, path, done) => {
        // merge custom options with defaultOptions..
        const printOptions = {
            ...defaultPrinterOptions,

            // add the path to the options.
            path: path
        }

        // create a function which can be stored in an array
        // it will later be grabbed by startPrinter() OR at the time any 
        // brwoser freed up.. 
        // the function needs to be passed the actual used browser instance!
        this.enqueuedPrintJobs.push(async(browser) => {

            // catch the error which may be produced when printing something..
            try {
                // print the document
                await this.print(browser, html, css, printOptions)
            } catch (err) {
                console.error('error when printing document..CLosing browser and starting a new job!!', printOptions.path)
                console.error(err)

                // store someting so you now what failed and coudl be retried or something..
                this.failedJobs.push({ html, css, path: printOptions.path })

                // puppeteer can run into erros too!! 
                // so close the browser and launch a new one!
                await this.closeBrowser(browser)
                browser = await this.launchBrowser()
            }

            // after the print, call done() so the promise is resovled in the right moment when 
            // this particular print has ended.!
            done()

            // start the next job right now  if there are any left.
            const job = this.enqueuedPrintJobs.shift()

            if (!job) {
                console.log('No print jobs available anymore. CLosing this browser instance.. Remaining browsers now:', this.maxBrowsers - this.browserInstances + 1)
                await this.closeBrowser(browser)
                return
            }

            // job is actually this function itself! It will be executed
            // and automatically grab a new job after completion :)
            // we pass the same browser instance to the next job!.
            await job(browser)
        })

        // whenever a print job added make sure to start the printer
        // this starts new browser instances if the limit is not exceeded resp. if no browser is instantiated yet,
        // and does nothing if maximum browser count is reached..
        this.tryStartPrinter()
    }

    // same as enqueuePrint except it wraps it in a promise so we can now the
    // exact end moment and await it..
    enqueuePrintPromise(html, css, path) {
        return new Promise((resolve, reject) => {
            try {
                this.enqueuePrint(html, css, path, resolve)
            } catch (err) {
                console.error('unexpected error when setting up print job..', err)
                reject(err)
            }
        })

    }

    // If browser instance limit is not reached will isntantiate a new one and run a print job with it.
    // a print job will automatically grab a next job with the created browser if there are any left.
    tryStartPrinter = async() => {

        // Max browser count in use OR no jobs left.
        if (this.browserInstances >= this.maxBrowsers || this.enqueuedPrintJobs.length === 0) {
            return
        }
        // browser instances available! 
        // create a new one 

        console.log('launching new browser. Available after launch:', this.maxBrowsers - this.browserInstances - 1)
        const browser = await this.launchBrowser()
        
        // run job
        const job = this.enqueuedPrintJobs.shift()
        await job(browser)

    }

    closeBrowser = async(browser) => {


        // decrement browsers in use!
        // important to call before closing browser!!
        this.browserInstances--
        await browser.close()

    }

    launchBrowser = async() => {
        // increment browsers in use!
        // important to increase before actualy launching (async stuff..)
        this.browserInstances++

        // this code you have to adjust according your enviromnemt..
        const browser = await puppeteer.launch({ headless: true })

        return browser
    }


    // The actual print function which creates a pdf.
    print = async(browser, html, css, printOptions) => {

        console.log('Converting page to pdf. path:', printOptions.path)
            // Run pdf creation in seperate page.
        const page = await browser.newPage()

        await page.setContent(html, { waitUntil: 'networkidle0' });
        await page.addStyleTag({ content: css });
        await page.pdf(printOptions);
        await page.close();

    }

}

// testing the PDFPrinter with some jobs.
// make sure to run the printer in an `async` function so u can 
// use await... 
const testPrinterQueue = async() => {

    // config
    const maxOpenedBrowsers = 5 // amount of browser instances which are allowed to be opened in parallel
    const testJobCount = 100 // amount of test pdf jobs to be created
    const destDir = 'C:\\somepath' // the directory to store the pdfs in..


    // create sample jobs for testing...
    const jobs = []
    for (let i = 0; i < testJobCount; i++) {
        jobs.push({
            html: `<h1>job number [${i}]</h1>`,
            css: 'h1 { background-color: red; }',
            path: require('path').join(destDir, `pdf_${i}.pdf`)
        })
    }

    // track time
    const label = 'printed a total of ' + testJobCount + ' pdfs!'
    console.time(label)

    // run the actual pdf generation..
    const printer = new PdfPrinter(maxOpenedBrowsers)

    const jobProms = []
    for (let job of jobs) {

        // run jobs in parallel. Each job wil be runned async and return a Promise therefor
        jobProms.push(
            printer.enqueuePrintPromise(job.html, job.css, job.path)
        )
    }

    console.log('All jobs enqueued!! Wating for finish now.')

    // helper function which awaits all the print jobs, resp. an array of promises.
    await Promise.all(jobProms)
    console.timeEnd(label)

    // failed jobs::
    console.log('jobs failed:', printer.failedJobs)

    // as file:
    await require('fs').promises.writeFile('failed-jobs.json', JSON.stringify(printer.failedJobs))
}


testPrinterQueue().then(() => {
    console.log('done with everyting..')
}).catch(err => {
    console.error('unexpected error occured while printing all pages...', err)
})
(async () => {
        browser = await Puppeteer.launch({
            headless: true,
            handleSIGINT: false,
            args: args,
        });

        const page = await browser.newPage();
    
        await page.setViewport({
            width: resolution.x,
            height: resolution.y,
        })

        await computeFirstTerm(page);
        await computeSecondTerm(page);
        await computeThirdTerm(page);
        browser.close()
    })()

//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};


function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    AsyncFunction();

    // what you have done in your code:
    (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction()
console.log('done')

Async named function started
Async anonymus function started
sync function ended. // => sync function already ended 
done   // sync function ended and code continues execution.
Async named function ended
Async anonymus function ended
//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};

// this is now async!!
async function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    await AsyncFunction();

    // what you have done in your code:
    await (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction().then(() => {
    console.log('done')
}).catch(err => {
    console.error('unexpected error occured..')
})

sync function started
Async named function started
Async named function ended
Async anonymus function started
Async anonymus function ended
sync function ended.
done

-----------------------

var puppeteer = require('puppeteer')

const defaultPrinterOptions = {
    format: 'A4',
    printBackground: true,
    margin: {
        left: '0px',
        top: '0px',
        right: '0px',
        bottom: '0px'
    }
}

class PdfPrinter {

    maxBrowsers = 2
    enqueuedPrintJobs = []
    failedJobs = []
    browserInstances = 0

    // max browser instances in parallel 
    constructor(maxBrowsers) {
        this.maxBrowsers = maxBrowsers
    }

    /**
     * 
     * @param {*} html the html content to print
     * @param {*} css to apply to the page
     * @param {*} printOptions options passed to puppeteer
     */
    // enqueues a print but the exact end moment cannot be known..
    enqueuePrint = (html, css, path, done) => {
        // merge custom options with defaultOptions..
        const printOptions = {
            ...defaultPrinterOptions,

            // add the path to the options.
            path: path
        }

        // create a function which can be stored in an array
        // it will later be grabbed by startPrinter() OR at the time any 
        // brwoser freed up.. 
        // the function needs to be passed the actual used browser instance!
        this.enqueuedPrintJobs.push(async(browser) => {

            // catch the error which may be produced when printing something..
            try {
                // print the document
                await this.print(browser, html, css, printOptions)
            } catch (err) {
                console.error('error when printing document..CLosing browser and starting a new job!!', printOptions.path)
                console.error(err)

                // store someting so you now what failed and coudl be retried or something..
                this.failedJobs.push({ html, css, path: printOptions.path })

                // puppeteer can run into erros too!! 
                // so close the browser and launch a new one!
                await this.closeBrowser(browser)
                browser = await this.launchBrowser()
            }

            // after the print, call done() so the promise is resovled in the right moment when 
            // this particular print has ended.!
            done()

            // start the next job right now  if there are any left.
            const job = this.enqueuedPrintJobs.shift()

            if (!job) {
                console.log('No print jobs available anymore. CLosing this browser instance.. Remaining browsers now:', this.maxBrowsers - this.browserInstances + 1)
                await this.closeBrowser(browser)
                return
            }

            // job is actually this function itself! It will be executed
            // and automatically grab a new job after completion :)
            // we pass the same browser instance to the next job!.
            await job(browser)
        })

        // whenever a print job added make sure to start the printer
        // this starts new browser instances if the limit is not exceeded resp. if no browser is instantiated yet,
        // and does nothing if maximum browser count is reached..
        this.tryStartPrinter()
    }

    // same as enqueuePrint except it wraps it in a promise so we can now the
    // exact end moment and await it..
    enqueuePrintPromise(html, css, path) {
        return new Promise((resolve, reject) => {
            try {
                this.enqueuePrint(html, css, path, resolve)
            } catch (err) {
                console.error('unexpected error when setting up print job..', err)
                reject(err)
            }
        })

    }

    // If browser instance limit is not reached will isntantiate a new one and run a print job with it.
    // a print job will automatically grab a next job with the created browser if there are any left.
    tryStartPrinter = async() => {

        // Max browser count in use OR no jobs left.
        if (this.browserInstances >= this.maxBrowsers || this.enqueuedPrintJobs.length === 0) {
            return
        }
        // browser instances available! 
        // create a new one 

        console.log('launching new browser. Available after launch:', this.maxBrowsers - this.browserInstances - 1)
        const browser = await this.launchBrowser()
        
        // run job
        const job = this.enqueuedPrintJobs.shift()
        await job(browser)

    }

    closeBrowser = async(browser) => {


        // decrement browsers in use!
        // important to call before closing browser!!
        this.browserInstances--
        await browser.close()

    }

    launchBrowser = async() => {
        // increment browsers in use!
        // important to increase before actualy launching (async stuff..)
        this.browserInstances++

        // this code you have to adjust according your enviromnemt..
        const browser = await puppeteer.launch({ headless: true })

        return browser
    }


    // The actual print function which creates a pdf.
    print = async(browser, html, css, printOptions) => {

        console.log('Converting page to pdf. path:', printOptions.path)
            // Run pdf creation in seperate page.
        const page = await browser.newPage()

        await page.setContent(html, { waitUntil: 'networkidle0' });
        await page.addStyleTag({ content: css });
        await page.pdf(printOptions);
        await page.close();

    }

}

// testing the PDFPrinter with some jobs.
// make sure to run the printer in an `async` function so u can 
// use await... 
const testPrinterQueue = async() => {

    // config
    const maxOpenedBrowsers = 5 // amount of browser instances which are allowed to be opened in parallel
    const testJobCount = 100 // amount of test pdf jobs to be created
    const destDir = 'C:\\somepath' // the directory to store the pdfs in..


    // create sample jobs for testing...
    const jobs = []
    for (let i = 0; i < testJobCount; i++) {
        jobs.push({
            html: `<h1>job number [${i}]</h1>`,
            css: 'h1 { background-color: red; }',
            path: require('path').join(destDir, `pdf_${i}.pdf`)
        })
    }

    // track time
    const label = 'printed a total of ' + testJobCount + ' pdfs!'
    console.time(label)

    // run the actual pdf generation..
    const printer = new PdfPrinter(maxOpenedBrowsers)

    const jobProms = []
    for (let job of jobs) {

        // run jobs in parallel. Each job wil be runned async and return a Promise therefor
        jobProms.push(
            printer.enqueuePrintPromise(job.html, job.css, job.path)
        )
    }

    console.log('All jobs enqueued!! Wating for finish now.')

    // helper function which awaits all the print jobs, resp. an array of promises.
    await Promise.all(jobProms)
    console.timeEnd(label)

    // failed jobs::
    console.log('jobs failed:', printer.failedJobs)

    // as file:
    await require('fs').promises.writeFile('failed-jobs.json', JSON.stringify(printer.failedJobs))
}


testPrinterQueue().then(() => {
    console.log('done with everyting..')
}).catch(err => {
    console.error('unexpected error occured while printing all pages...', err)
})
(async () => {
        browser = await Puppeteer.launch({
            headless: true,
            handleSIGINT: false,
            args: args,
        });

        const page = await browser.newPage();
    
        await page.setViewport({
            width: resolution.x,
            height: resolution.y,
        })

        await computeFirstTerm(page);
        await computeSecondTerm(page);
        await computeThirdTerm(page);
        browser.close()
    })()

//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};


function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    AsyncFunction();

    // what you have done in your code:
    (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction()
console.log('done')

Async named function started
Async anonymus function started
sync function ended. // => sync function already ended 
done   // sync function ended and code continues execution.
Async named function ended
Async anonymus function ended
//utility
function wait(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

const AsyncFunction = async() => {
    console.log('Async named function started')
        // simulate execution time of 2 seconds
    await wait(2000)

    console.log('Async named function ended')
};

// this is now async!!
async function SyncFunction() {
    console.log('sync function started')

    // example of async function execution within a sync function..
    await AsyncFunction();

    // what you have done in your code:
    await (async() => {
        console.log('Async anonymus function started')
        await wait(3000)
        console.log('Async anonymus function ended')

    })()


    // what
    console.log('sync function ended.')
}

SyncFunction().then(() => {
    console.log('done')
}).catch(err => {
    console.error('unexpected error occured..')
})

sync function started
Async named function started
Async named function ended
Async anonymus function started
Async anonymus function ended
sync function ended.
done

Is there a way to include only one module in the bundle?

copy iconCopydownload iconDownload
{
   "main": "dist/index.js" // Or wherever you want to put the bundle.
   "targets": {
    "main": {
      "includeNodeModules": ["commons"]
    }
  }
}

List NPM workspaces similar to lerna ls

copy iconCopydownload iconDownload
file:../../packages/package1
file:../../packages/package2
packages/package1
packages/package2
-----------------------
file:../../packages/package1
file:../../packages/package2
packages/package1
packages/package2

Imports from a lerna shared package seem to require src at the end of the name (Typescript/javascript)

copy iconCopydownload iconDownload
export * from "./src";
import { GreatClass } from "../myShared";
-----------------------
export * from "./src";
import { GreatClass } from "../myShared";

how to delete all node_modules from all packages in npm 7 workspace monorepo

copy iconCopydownload iconDownload
npm exec --workspaces -- npx rimraf node_modules && npx rimraf node_modules
-----------------------
npx npkill

React native couldn't resolve local module after noHoist has been added to project

copy iconCopydownload iconDownload
const path = require('path');
const exclusionList = require('metro-config/src/defaults/exclusionList');
const getWorkspaces = require('get-yarn-workspaces');

function generateAssetsPath(depth, subpath) {
  return `/assets`.concat(
    Array.from({ length: depth })
      // eslint-disable-next-line no-unused-vars
      .map((_, i) => `/${subpath}`)
      .join(''),
  );
}

function getMetroAndroidAssetsResolutionFix(params = {}) {
  const { depth = 3 } = params;
  let publicPath = generateAssetsPath(depth, 'dir');
  const applyMiddleware = (middleware) => (req, res, next) => {
    // eslint-disable-next-line no-plusplus
    for (let currentDepth = depth; currentDepth >= 0; currentDepth--) {
      const pathToReplace = generateAssetsPath(currentDepth, 'dir');
      const replacementPath = generateAssetsPath(depth - currentDepth, '..');
      if (currentDepth === depth) {
        publicPath = pathToReplace;
      }
      if (req.url.startsWith(pathToReplace)) {
        req.url = req.url.replace(pathToReplace, replacementPath);
        break;
      }
    }
    return middleware(req, res, next);
  };
  return {
    publicPath,
    applyMiddleware,
  };
}

function getNohoistedPackages() {
  // eslint-disable-next-line global-require
  const monorepoRootPackageJson = require('../../package.json');
  const nohoistedPackages = monorepoRootPackageJson.workspaces.nohoist
    .filter((packageNameGlob) => !packageNameGlob.endsWith('**'))
    .map((packageNameGlob) => packageNameGlob.substring(3));
  return nohoistedPackages;
}

function getMetroNohoistSettings({
  dir,
  workspaceName,
  reactNativeAlias,
} = {}) {
  const nohoistedPackages = getNohoistedPackages();
  const blockList = [];
  const extraNodeModules = {};
  nohoistedPackages.forEach((packageName) => {
    extraNodeModules[packageName] =
      reactNativeAlias && packageName === 'react-native'
        ? path.resolve(dir, `./node_modules/${reactNativeAlias}`)
        : path.resolve(dir, `./node_modules/${packageName}`);
    const regexSafePackageName = packageName.replace('/', '\\/');
    blockList.push(
      new RegExp(
        `^((?!${workspaceName}).)*\\/node_modules\\/${regexSafePackageName}\\/.*$`,
      ),
    );
  });
  return { extraNodeModules, blockList };
}

const workspaces = getWorkspaces(__dirname);

const androidAssetsResolutionFix = getMetroAndroidAssetsResolutionFix({
  depth: 3,
});

const nohoistSettings = getMetroNohoistSettings({
  dir: __dirname,
  workspaceName: 'mobile',
});

module.exports = {
  transformer: {
    // Apply the Android assets resolution fix to the public path...
    // publicPath: androidAssetsResolutionFix.publicPath,
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
  // server: {
  //   // ...and to the server middleware.
  //   enhanceMiddleware: (middleware) =>
  //     androidAssetsResolutionFix.applyMiddleware(middleware),
  // },
  // Add additional Yarn workspace package roots to the module map.
  // This allows importing importing from all the project's packages.
  watchFolders: [
    path.resolve(__dirname, '../../node_modules'),
    ...workspaces.filter((workspaceDir) => !(workspaceDir === __dirname)),
  ],
  maxWorkers: 2,
  resolver: {
    // Ensure we resolve nohoisted packages from this directory.
    blockList: exclusionList(nohoistSettings.blockList),
    extraNodeModules: nohoistSettings.extraNodeModules,
  },
};

How to list every public workspace with Yarn 2+?

copy iconCopydownload iconDownload
yarn constraints query "workspace(Cwd), \+ workspace_field(Cwd, 'private', true), workspace_ident(Cwd, Ident)" --json
{"Cwd":"packages/yarnpkg-sdks","Ident":"@yarnpkg/sdks"}
{"Cwd":"packages/yarnpkg-shell","Ident":"@yarnpkg/shell"}
-----------------------
yarn constraints query "workspace(Cwd), \+ workspace_field(Cwd, 'private', true), workspace_ident(Cwd, Ident)" --json
{"Cwd":"packages/yarnpkg-sdks","Ident":"@yarnpkg/sdks"}
{"Cwd":"packages/yarnpkg-shell","Ident":"@yarnpkg/shell"}

How to make Navigation work with Routes if they are in the different packages?

copy iconCopydownload iconDownload
class MyComponent extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick(c) {
  
this.props.history.push(`/main/${c.name}`)
}

How to run jest by lerna in github actions

copy iconCopydownload iconDownload
on:
  pull_request:
    branches: [ master ]

jobs:
  test_pull_request:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
        with:
          node-version: 12
      
      # fix issue with lerna and clean installs
      - run: lerna bootstrap --no-ci  
      - run: npm test

Community Discussions

Trending Discussions on lerna
  • How to filter NPM commands to a pattern of workspaces (like filter, include, exclude, glob, grep or subdirectory)?
  • Puppeteer create PDF files from HTML data hangs Windows 10 system
  • Lerna: not killing processes after CTRL+C
  • Vercel deployment error: Module Not Found remotelly works locally. Cached build is the problem?
  • Cannot find file ReactRefreshEntry.js
  • Lerna Detached git HEAD error in Azure devOps pipeline
  • Is there a way to include only one module in the bundle?
  • List NPM workspaces similar to lerna ls
  • Imports from a lerna shared package seem to require src at the end of the name (Typescript/javascript)
  • how to delete all node_modules from all packages in npm 7 workspace monorepo
Trending Discussions on lerna

QUESTION

How to filter NPM commands to a pattern of workspaces (like filter, include, exclude, glob, grep or subdirectory)?

Asked 2022-Mar-25 at 13:38

I'd like to organise a large NPM monorepo such that I can run commands on many (but not all) workspaces according to a category or pattern.

This could be by subdirectory, or by a pattern in the workspace names like a prefix or suffix, but I can't see any way to do either in NPM alone.


In Yarn >= 2, this is possible using --include or --exclude flags with glob patterns on yarn workspaces foreach, for example:

yarn workspaces foreach --include "@namespace/plugin-*" --include "@namespace/preset-*" run build

...and that builds all your workspaces with that namespace and either the plugin- or preset- prefix.


In lerna, the --scope flag also took globs allowing patterns, for example:

lerna run --scope "@namespace/plugin-*" --scope "@namespace/preset-*" run build

But in NPM, as far I can see in NPM's workspaces documentation for v7 and for v8, it doesn't seem to have the same feature:

  • It has a flag --workspace which may be used multiple times to create an array but appears to only accept exact workspace names,
  • ...and a flag --workspaces which appears to run in all workspaces,

...but I can't see any way to either run on all workspaces in a directory or all workspaces matching a pattern. I really don't want to have to list every workspace by name in every script, as there's going to be a lot of them.

ANSWER

Answered 2022-Mar-22 at 10:06

It's not documented (at time of asking), but NPM can filter workspace commands to subdirectories of workspaces by giving the --workspace flag a path as its value. For example:

npm run --workspace packages/presets --workspace packages/plugins build

This will find workspaces that are directly in $project_root/packages/presets/ or $project_root/packages/plugins/, but not workspaces in subdirectories of these subdirectories.

Deeper-nested subdirectories can be included using /**, like:

npm run --workspace packages/** build

The above examples would work with workspaces organised into subdirectories, defined in package.json like:

  "workspaces": [
    "packages/plugins/*",
    "packages/presets/*",
    ...more
  ],

...or a catch-all like:

  "workspaces": [
    "packages/**",
    ...more
  ],

While pointing --workspace to subdirectories of workspaces instead of individual workspaces like this doesn't seem to be documented anywhere at time of writing, it does appear to be an intentional, planned, supported feature. I found a note proposing it deep in one of the rfcs:

Note: Globs are not supported as a valid --workspace argument value, the proposed alternative is to use npm --workspace= in which is a folder containing multiple workspaces.

I couldn't find anything explicitly stating that this proposal was implemented, but I tried reorganising my monorepo into subdirectories and using a subdirectory with the --workspace flag, and it worked.

Their reason for choosing paths rather than glob patterns in workspace names (like yarn does and lerna did) appears to be because of the:

many pitfalls of supporting globs in the variety of supported shells and operational systems

Source https://stackoverflow.com/questions/71350521

Community Discussions, Code Snippets contain sources that include Stack Exchange Network

Vulnerabilities

No vulnerabilities reported

Install lerna

The instructions below are for Lerna 3.x. We recommend using it instead of 2.x for a new Lerna project. Let's start by installing Lerna as a dev dependency of your project with npm.

Support

If you encounter any issues while using Lerna please check out our Troubleshooting document where you might find the answer to your problem.

DOWNLOAD this Library from

Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

Explore Related Topics

Share this Page

share link
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

  • © 2022 Open Weaver Inc.