sebastianwessel / quickjs

A typescript package to execute JavaScript and TypeScript code in a webassembly quickjs sandbox
https://sebastianwessel.github.io/quickjs/
MIT License
579 stars 13 forks source link

[Issue]: readFile is splitting files in VFS src #45

Closed MarketingPip closed 2 days ago

MarketingPip commented 3 weeks ago

When readFile is calling a file inside "src" like

{
   "src": {
       "textFile.txt": "Hello from the text file!",
   }
}

import { readFileSync, readFile, writeFileSync } from 'node:fs'
async function run(){
readFile('./textFile.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

console.log(readFileSync('./textFile.txt'))
}
await run()

we get:

Hello;
from;
the;
text;
file;
Hello;
from;
the;
text;
file;

When not in src like:

{
   "src": {},
   "textFile.txt": "Hello from the text file!",
}

We get:

Hello from the text file!
Hello from the text file!
sebastianwessel commented 3 weeks ago

What exactly is the issue?

This one is event/stream based, where you get only partial parts, which are printed out to the console log. Each partial data is printed out as a new line.

readFile('./textFile.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

This prints:

Hello from the text file!

The other console.log(readFileSync('./textFile.txt')) will read the whole file content and as it is sync, it will block until the whole file content is read and printed out. This prints:

Hello from the text file!

The single line will be printed out first, as the stream based one is executed in the next tick, after console.log(readFileSync('./textFile.txt')) has finished

MarketingPip commented 3 weeks ago

@sebastianwessel - my bad. It seems I have documented this issue in correctly. See below (and revised above)....

When using like this:

{
   "src": {
       "textFile.txt": "Hello from the text file!",
   }
}

import { readFileSync, readFile, writeFileSync } from 'node:fs'
async function run(){
readFile('./textFile.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

console.log(readFileSync('./textFile.txt'))
}
await run()

we get:

Hello;
from;
the;
text;
file;
Hello;
from;
the;
text;
file;
sebastianwessel commented 3 days ago

Your code must be at least look like the code below, as readFile is event based. The code execution will continue after call readFile, while calling the callback.

import { readFileSync, readFile, writeFileSync } from 'node:fs'
async function run(){

await new Promise((resolve)=>{
  readFile('./textFile.txt', 'utf8', (err, data) => {
    if (err) throw err;
    console.log('1', data);
    resolve()
  });
})

console.log('2',readFileSync('./textFile.txt'))
}
await run()

The output without the Promise is

2 Hello from the text file!
1 Hello from the text file!

I tried it on the current working branch, and there are no new lines at all, as - as far as I remember - it is always readFileSync behind the scene. We use a vfs, and we have the file already in memory anyway.

MarketingPip commented 2 days ago

@sebastianwessel - just digging into this on my end. This seems to be an issue with MY code and not the library.

TDLR; My output handler wasn't properly formatting things.