Socket
Socket
Sign inDemoInstall

@rollup/plugin-terser

Package Overview
Dependencies
Maintainers
4
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rollup/plugin-terser - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

src/constants.ts

159

dist/cjs/index.js

@@ -5,3 +5,2 @@ 'use strict';

var process = require('process');
var worker_threads = require('worker_threads');

@@ -11,2 +10,3 @@ var smob = require('smob');

var url = require('url');
var async_hooks = require('async_hooks');
var os = require('os');

@@ -28,13 +28,16 @@ var events = require('events');

}
async function runWorker() {
if (worker_threads.isMainThread || !worker_threads.parentPort || !isWorkerContextSerialized(worker_threads.workerData)) {
function runWorker() {
if (worker_threads.isMainThread || !worker_threads.parentPort) {
return;
}
try {
// eslint-disable-next-line no-eval
const eval2 = eval;
const options = eval2(`(${worker_threads.workerData.options})`);
const result = await terser$1.minify(worker_threads.workerData.code, options);
// eslint-disable-next-line no-eval
const eval2 = eval;
worker_threads.parentPort.on('message', async (data) => {
if (!isWorkerContextSerialized(data)) {
return;
}
const options = eval2(`(${data.options})`);
const result = await terser$1.minify(data.code, options);
const output = {
code: result.code || worker_threads.workerData.code,
code: result.code || data.code,
nameCache: options.nameCache

@@ -48,10 +51,19 @@ };

}
worker_threads.parentPort.postMessage(output);
worker_threads.parentPort === null || worker_threads.parentPort === void 0 ? void 0 : worker_threads.parentPort.postMessage(output);
});
}
const taskInfo = Symbol('taskInfo');
const freeWorker = Symbol('freeWorker');
class WorkerPoolTaskInfo extends async_hooks.AsyncResource {
constructor(callback) {
super('WorkerPoolTaskInfo');
this.callback = callback;
}
catch (e) {
process.exit(1);
done(err, result) {
this.runInAsyncScope(this.callback, null, err, result);
this.emitDestroy();
}
}
const symbol = Symbol.for('FreeWoker');
class WorkerPool extends events.EventEmitter {

@@ -61,24 +73,19 @@ constructor(options) {

this.tasks = [];
this.workers = 0;
this.workers = [];
this.freeWorkers = [];
this.maxInstances = options.maxWorkers || os.cpus().length;
this.filePath = options.filePath;
this.on(symbol, () => {
this.on(freeWorker, () => {
if (this.tasks.length > 0) {
this.run();
const { context, cb } = this.tasks.shift();
this.runTask(context, cb);
}
});
}
add(context, cb) {
this.tasks.push({
context,
cb
});
if (this.workers >= this.maxInstances) {
return;
}
this.run();
get numWorkers() {
return this.workers.length;
}
async addAsync(context) {
addAsync(context) {
return new Promise((resolve, reject) => {
this.add(context, (err, output) => {
this.runTask(context, (err, output) => {
if (err) {

@@ -96,39 +103,48 @@ reject(err);

}
run() {
if (this.tasks.length === 0) {
return;
close() {
for (let i = 0; i < this.workers.length; i++) {
const worker = this.workers[i];
worker.terminate();
}
const task = this.tasks.shift();
if (typeof task === 'undefined') {
return;
}
this.workers += 1;
let called = false;
const callCallback = (err, output) => {
if (called) {
return;
}
called = true;
this.workers -= 1;
task.cb(err, output);
this.emit(symbol);
};
const worker = new worker_threads.Worker(this.filePath, {
workerData: {
code: task.context.code,
options: serializeJavascript(task.context.options)
}
}
addNewWorker() {
const worker = new worker_threads.Worker(this.filePath);
worker.on('message', (result) => {
var _a;
(_a = worker[taskInfo]) === null || _a === void 0 ? void 0 : _a.done(null, result);
worker[taskInfo] = null;
this.freeWorkers.push(worker);
this.emit(freeWorker);
});
worker.on('message', (data) => {
callCallback(null, data);
});
worker.on('error', (err) => {
callCallback(err);
});
worker.on('exit', (code) => {
if (code !== 0) {
callCallback(new Error(`Minify worker stopped with exit code ${code}`));
if (worker[taskInfo]) {
worker[taskInfo].done(err, null);
}
else {
this.emit('error', err);
}
this.workers.splice(this.workers.indexOf(worker), 1);
this.addNewWorker();
});
this.workers.push(worker);
this.freeWorkers.push(worker);
this.emit(freeWorker);
}
runTask(context, cb) {
if (this.freeWorkers.length === 0) {
this.tasks.push({ context, cb });
if (this.numWorkers < this.maxInstances) {
this.addNewWorker();
}
return;
}
const worker = this.freeWorkers.pop();
if (worker) {
worker[taskInfo] = new WorkerPoolTaskInfo(cb);
worker.postMessage({
code: context.code,
options: serializeJavascript(context.options)
});
}
}
}

@@ -138,9 +154,15 @@

const { maxWorkers, ...options } = input;
const workerPool = new WorkerPool({
filePath: url.fileURLToPath((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.js', document.baseURI).href))),
maxWorkers
});
let workerPool;
let numOfChunks = 0;
let numOfWorkersUsed = 0;
return {
name: 'terser',
async renderChunk(code, chunk, outputOptions) {
if (!workerPool) {
workerPool = new WorkerPool({
filePath: url.fileURLToPath((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.js', document.baseURI).href))),
maxWorkers
});
}
numOfChunks += 1;
const defaultOptions = {

@@ -194,2 +216,13 @@ sourceMap: outputOptions.sourcemap === true || typeof outputOptions.sourcemap === 'string'

}
finally {
numOfChunks -= 1;
if (numOfChunks === 0) {
numOfWorkersUsed = workerPool.numWorkers;
workerPool.close();
workerPool = null;
}
}
},
get numOfWorkersUsed() {
return numOfWorkersUsed;
}

@@ -196,0 +229,0 @@ };

@@ -1,6 +0,6 @@

import process from 'process';
import { isMainThread, parentPort, workerData, Worker } from 'worker_threads';
import { isMainThread, parentPort, Worker } from 'worker_threads';
import { isObject, hasOwnProperty, merge } from 'smob';
import { minify } from 'terser';
import { fileURLToPath } from 'url';
import { AsyncResource } from 'async_hooks';
import { cpus } from 'os';

@@ -22,13 +22,16 @@ import { EventEmitter } from 'events';

}
async function runWorker() {
if (isMainThread || !parentPort || !isWorkerContextSerialized(workerData)) {
function runWorker() {
if (isMainThread || !parentPort) {
return;
}
try {
// eslint-disable-next-line no-eval
const eval2 = eval;
const options = eval2(`(${workerData.options})`);
const result = await minify(workerData.code, options);
// eslint-disable-next-line no-eval
const eval2 = eval;
parentPort.on('message', async (data) => {
if (!isWorkerContextSerialized(data)) {
return;
}
const options = eval2(`(${data.options})`);
const result = await minify(data.code, options);
const output = {
code: result.code || workerData.code,
code: result.code || data.code,
nameCache: options.nameCache

@@ -42,10 +45,19 @@ };

}
parentPort.postMessage(output);
parentPort === null || parentPort === void 0 ? void 0 : parentPort.postMessage(output);
});
}
const taskInfo = Symbol('taskInfo');
const freeWorker = Symbol('freeWorker');
class WorkerPoolTaskInfo extends AsyncResource {
constructor(callback) {
super('WorkerPoolTaskInfo');
this.callback = callback;
}
catch (e) {
process.exit(1);
done(err, result) {
this.runInAsyncScope(this.callback, null, err, result);
this.emitDestroy();
}
}
const symbol = Symbol.for('FreeWoker');
class WorkerPool extends EventEmitter {

@@ -55,24 +67,19 @@ constructor(options) {

this.tasks = [];
this.workers = 0;
this.workers = [];
this.freeWorkers = [];
this.maxInstances = options.maxWorkers || cpus().length;
this.filePath = options.filePath;
this.on(symbol, () => {
this.on(freeWorker, () => {
if (this.tasks.length > 0) {
this.run();
const { context, cb } = this.tasks.shift();
this.runTask(context, cb);
}
});
}
add(context, cb) {
this.tasks.push({
context,
cb
});
if (this.workers >= this.maxInstances) {
return;
}
this.run();
get numWorkers() {
return this.workers.length;
}
async addAsync(context) {
addAsync(context) {
return new Promise((resolve, reject) => {
this.add(context, (err, output) => {
this.runTask(context, (err, output) => {
if (err) {

@@ -90,39 +97,48 @@ reject(err);

}
run() {
if (this.tasks.length === 0) {
return;
close() {
for (let i = 0; i < this.workers.length; i++) {
const worker = this.workers[i];
worker.terminate();
}
const task = this.tasks.shift();
if (typeof task === 'undefined') {
return;
}
this.workers += 1;
let called = false;
const callCallback = (err, output) => {
if (called) {
return;
}
called = true;
this.workers -= 1;
task.cb(err, output);
this.emit(symbol);
};
const worker = new Worker(this.filePath, {
workerData: {
code: task.context.code,
options: serializeJavascript(task.context.options)
}
}
addNewWorker() {
const worker = new Worker(this.filePath);
worker.on('message', (result) => {
var _a;
(_a = worker[taskInfo]) === null || _a === void 0 ? void 0 : _a.done(null, result);
worker[taskInfo] = null;
this.freeWorkers.push(worker);
this.emit(freeWorker);
});
worker.on('message', (data) => {
callCallback(null, data);
});
worker.on('error', (err) => {
callCallback(err);
});
worker.on('exit', (code) => {
if (code !== 0) {
callCallback(new Error(`Minify worker stopped with exit code ${code}`));
if (worker[taskInfo]) {
worker[taskInfo].done(err, null);
}
else {
this.emit('error', err);
}
this.workers.splice(this.workers.indexOf(worker), 1);
this.addNewWorker();
});
this.workers.push(worker);
this.freeWorkers.push(worker);
this.emit(freeWorker);
}
runTask(context, cb) {
if (this.freeWorkers.length === 0) {
this.tasks.push({ context, cb });
if (this.numWorkers < this.maxInstances) {
this.addNewWorker();
}
return;
}
const worker = this.freeWorkers.pop();
if (worker) {
worker[taskInfo] = new WorkerPoolTaskInfo(cb);
worker.postMessage({
code: context.code,
options: serializeJavascript(context.options)
});
}
}
}

@@ -132,9 +148,15 @@

const { maxWorkers, ...options } = input;
const workerPool = new WorkerPool({
filePath: fileURLToPath(import.meta.url),
maxWorkers
});
let workerPool;
let numOfChunks = 0;
let numOfWorkersUsed = 0;
return {
name: 'terser',
async renderChunk(code, chunk, outputOptions) {
if (!workerPool) {
workerPool = new WorkerPool({
filePath: fileURLToPath(import.meta.url),
maxWorkers
});
}
numOfChunks += 1;
const defaultOptions = {

@@ -188,2 +210,13 @@ sourceMap: outputOptions.sourcemap === true || typeof outputOptions.sourcemap === 'string'

}
finally {
numOfChunks -= 1;
if (numOfChunks === 0) {
numOfWorkersUsed = workerPool.numWorkers;
workerPool.close();
workerPool = null;
}
}
},
get numOfWorkersUsed() {
return numOfWorkersUsed;
}

@@ -190,0 +223,0 @@ };

{
"name": "@rollup/plugin-terser",
"version": "0.3.0",
"version": "0.4.0",
"publishConfig": {

@@ -5,0 +5,0 @@ "access": "public"

@@ -12,6 +12,5 @@ import { fileURLToPath } from 'url';

const workerPool = new WorkerPool({
filePath: fileURLToPath(import.meta.url),
maxWorkers
});
let workerPool: WorkerPool | null | undefined;
let numOfChunks = 0;
let numOfWorkersUsed = 0;

@@ -22,2 +21,11 @@ return {

async renderChunk(code: string, chunk: RenderedChunk, outputOptions: NormalizedOutputOptions) {
if (!workerPool) {
workerPool = new WorkerPool({
filePath: fileURLToPath(import.meta.url),
maxWorkers
});
}
numOfChunks += 1;
const defaultOptions: Options = {

@@ -85,5 +93,16 @@ sourceMap: outputOptions.sourcemap === true || typeof outputOptions.sourcemap === 'string'

return Promise.reject(e);
} finally {
numOfChunks -= 1;
if (numOfChunks === 0) {
numOfWorkersUsed = workerPool.numWorkers;
workerPool.close();
workerPool = null;
}
}
},
get numOfWorkersUsed() {
return numOfWorkersUsed;
}
};
}

@@ -0,3 +1,8 @@

import type { AsyncResource } from 'async_hooks';
import type { Worker } from 'worker_threads';
import type { MinifyOptions } from 'terser';
import type { taskInfo } from './constants';
export interface Options extends MinifyOptions {

@@ -15,2 +20,8 @@ nameCache?: Record<string, any>;

interface WorkerPoolTaskInfo extends AsyncResource {
done(err: Error | null, result: any): void;
}
export type WorkerWithTaskInfo = Worker & { [taskInfo]?: WorkerPoolTaskInfo | null };
export interface WorkerContextSerialized {

@@ -17,0 +28,0 @@ code: string;

@@ -0,1 +1,2 @@

import { AsyncResource } from 'async_hooks';
import { Worker } from 'worker_threads';

@@ -7,2 +8,4 @@ import { cpus } from 'os';

import { freeWorker, taskInfo } from './constants';
import type {

@@ -13,7 +16,17 @@ WorkerCallback,

WorkerPoolOptions,
WorkerPoolTask
WorkerPoolTask,
WorkerWithTaskInfo
} from './type';
const symbol = Symbol.for('FreeWoker');
class WorkerPoolTaskInfo extends AsyncResource {
constructor(private callback: WorkerCallback) {
super('WorkerPoolTaskInfo');
}
done(err: Error | null, result: any) {
this.runInAsyncScope(this.callback, null, err, result);
this.emitDestroy();
}
}
export class WorkerPool extends EventEmitter {

@@ -26,3 +39,4 @@ protected maxInstances: number;

protected workers = 0;
protected workers: WorkerWithTaskInfo[] = [];
protected freeWorkers: WorkerWithTaskInfo[] = [];

@@ -35,5 +49,6 @@ constructor(options: WorkerPoolOptions) {

this.on(symbol, () => {
this.on(freeWorker, () => {
if (this.tasks.length > 0) {
this.run();
const { context, cb } = this.tasks.shift()!;
this.runTask(context, cb);
}

@@ -43,18 +58,9 @@ });

add(context: WorkerContext, cb: WorkerCallback) {
this.tasks.push({
context,
cb
});
if (this.workers >= this.maxInstances) {
return;
}
this.run();
get numWorkers(): number {
return this.workers.length;
}
async addAsync(context: WorkerContext): Promise<WorkerOutput> {
addAsync(context: WorkerContext): Promise<WorkerOutput> {
return new Promise((resolve, reject) => {
this.add(context, (err, output) => {
this.runTask(context, (err, output) => {
if (err) {

@@ -75,49 +81,52 @@ reject(err);

private run() {
if (this.tasks.length === 0) {
return;
close() {
for (let i = 0; i < this.workers.length; i++) {
const worker = this.workers[i];
worker.terminate();
}
}
const task = this.tasks.shift();
private addNewWorker() {
const worker: WorkerWithTaskInfo = new Worker(this.filePath);
if (typeof task === 'undefined') {
return;
}
worker.on('message', (result) => {
worker[taskInfo]?.done(null, result);
worker[taskInfo] = null;
this.freeWorkers.push(worker);
this.emit(freeWorker);
});
this.workers += 1;
let called = false;
const callCallback = (err: Error | null, output?: WorkerOutput) => {
if (called) {
return;
worker.on('error', (err) => {
if (worker[taskInfo]) {
worker[taskInfo].done(err, null);
} else {
this.emit('error', err);
}
called = true;
this.workers.splice(this.workers.indexOf(worker), 1);
this.addNewWorker();
});
this.workers -= 1;
this.workers.push(worker);
this.freeWorkers.push(worker);
this.emit(freeWorker);
}
task.cb(err, output);
this.emit(symbol);
};
const worker = new Worker(this.filePath, {
workerData: {
code: task.context.code,
options: serializeJavascript(task.context.options)
private runTask(context: WorkerContext, cb: WorkerCallback) {
if (this.freeWorkers.length === 0) {
this.tasks.push({ context, cb });
if (this.numWorkers < this.maxInstances) {
this.addNewWorker();
}
});
return;
}
worker.on('message', (data) => {
callCallback(null, data);
});
worker.on('error', (err) => {
callCallback(err);
});
worker.on('exit', (code) => {
if (code !== 0) {
callCallback(new Error(`Minify worker stopped with exit code ${code}`));
}
});
const worker = this.freeWorkers.pop();
if (worker) {
worker[taskInfo] = new WorkerPoolTaskInfo(cb);
worker.postMessage({
code: context.code,
options: serializeJavascript(context.options)
});
}
}
}

@@ -1,3 +0,2 @@

import process from 'process';
import { isMainThread, parentPort, workerData } from 'worker_threads';
import { isMainThread, parentPort } from 'worker_threads';

@@ -25,17 +24,21 @@ import { hasOwnProperty, isObject } from 'smob';

export async function runWorker() {
if (isMainThread || !parentPort || !isWorkerContextSerialized(workerData)) {
export function runWorker() {
if (isMainThread || !parentPort) {
return;
}
try {
// eslint-disable-next-line no-eval
const eval2 = eval;
// eslint-disable-next-line no-eval
const eval2 = eval;
const options = eval2(`(${workerData.options})`);
parentPort.on('message', async (data: WorkerContextSerialized) => {
if (!isWorkerContextSerialized(data)) {
return;
}
const result = await minify(workerData.code, options);
const options = eval2(`(${data.options})`);
const result = await minify(data.code, options);
const output: WorkerOutput = {
code: result.code || workerData.code,
code: result.code || data.code,
nameCache: options.nameCache

@@ -52,6 +55,4 @@ };

parentPort.postMessage(output);
} catch (e) {
process.exit(1);
}
parentPort?.postMessage(output);
});
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc