'use strict'
const spawn = require('child_process').spawn;

let verbose = false;

const log = console.error.bind(console, "[Rworker.js] ")

const trace = (blabla) => {
	if(verbose) log(blabla);
};

module.exports.Rworker = class {

	constructor(id){
		this.id = id;
		this.thread = [];
		this.R = spawn('R', ['--vanilla']);

		this.R.on('error', (err) => {
			console.log('Failed to start child R process.');
		});

		this.R.on('close', (code) => {
			console.log(`R process exited with code ${code}`);
		});

		this.R.stdout.on('end', () => {
			console.log('----------------/');
		});

		this.R.stdout.on('data', (data) => {

			data = data.toString('utf8')
				.split('\n')
				.filter((line) => line.startsWith('['))
				.join('\n')

			// avoid 'welcome page' to be treated
			if(data.length != 0){
				// sometimes, w/ a lot of concurrent accesses, R return some "blanks lines like "[1]
				// this check wether the result is given or not, and retick() if not
				if (data.substring(data.lastIndexOf(']')+1, data.length).trim().length === 0) this.tick();
				else {
					trace('(#' + this.id + ') ' + 'R> ' + data);
					let task = this.thread[0];
					task.status = 'done' ;
					task.cb(null, data);
					this.tick();
				}
			}
		});
	}

	tick(){
		// clean finished ops
		this.thread = this.thread.filter((task) => (task.status === 'done') ? false : true);
		// starts the next op
		if(this.thread.length > 0){
			trace('(#' + this.id + ') ' + "pushing " + this.thread[0].cmd + " to stdin");
			this.R.stdin.write(this.thread[0].cmd + '\n', 'utf8');
		}else{
			trace('(#' + this.id + ') ' + 'all jobs done');
		}
	}

	Rexec(cmd, cb){
		trace('(#' + this.id + ') ' + "Rexec called with args " + cmd);
		this.thread.push({
			"cmd" : cmd,
			"cb" : cb,
			"status" : 'pending'
		});
		this.tick();
	}

}

@@ -656,159 +656,329 @@
 f8')
+;%0A
 %0A%09%09%09
-%09.split('%5Cn')%0A%09%09%09%09.filter((line) =%3E line.startsWith('%5B'))%0A%09%09%09%09.join('%5Cn')%0A%0A%09%09%09// avoid 'welcome page' to be treated
+trace('(#' + this.id + ') ' + 'R%3E%3E ' + data);%0A%0A%09%09%09if(!this.thread%5B0%5D) trace('(#' + this.id + ') ' + 'R%3E ' + data); //start screen%0A%09%09%09else%7B%0A%09%09%09%09let task = this.thread%5B0%5D;%0A%09%09%09%09task.output += data ;%0A%09%09%09%09if(data.startsWith('%3E ') %7C%7C data.endsWith('%3E '))%7B // previous exec is done
 %0A%09%09%09
-if(
+%09%09
 data
-.length != 0)%7B
+ = task.output ;
 %0A%09%09%09%09
+%09
 //
+ note :
  som
@@ -1045,16 +1045,17 @@
 ks lines
+%22
  like %22%5B
@@ -1060,21 +1060,26 @@
 %22%5B1%5D
+   %22
 %0A%09%09%09%09
+%09
 // this 
 chec
@@ -1078,13 +1078,24 @@
 his 
+condition 
 check
+s
  wet
@@ -1132,16 +1132,17 @@
 , and re
+-
 tick() i
@@ -1151,16 +1151,17 @@
 not%0A%09%09%09%09
+%09
 if (data
@@ -1227,44 +1227,22 @@
 gth 
-=
+!
 == 0)
- this.tick();%0A%09%09%09%09else
  %7B%0A%09%09%09%09%09
 trac
@@ -1237,16 +1237,17 @@
  %7B%0A%09%09%09%09%09
+%09
 trace('(
@@ -1288,39 +1288,8 @@
 );%0A%09
-%09%09%09%09let task = this.thread%5B0%5D;%0A
 %09%09%09%09
@@ -1313,24 +1313,25 @@
 one' ;%0A%09%09%09%09%09
+%09
 task.cb(null
@@ -1332,22 +1332,36 @@
 b(null, 
-data);
+task.output);%0A%09%09%09%09%09%7D
 %0A%09%09%09%09%09th
@@ -1907,16 +1907,34 @@
 %22 : cb,%0A
+%09%09%09%22output%22 : %22%22,%0A
 %09%09%09%22stat

FIX multi-line results