Skip to content

WebStreams all the things#770

Merged
saghul merged 10 commits intomasterfrom
new-streams-api
Feb 10, 2026
Merged

WebStreams all the things#770
saghul merged 10 commits intomasterfrom
new-streams-api

Conversation

@saghul
Copy link
Copy Markdown
Owner

@saghul saghul commented Feb 8, 2026

  • child process stdio
  • own process stdio
  • sockets
  • files (optional, with readable / writable properties)

@saghul saghul force-pushed the new-streams-api branch 2 times, most recently from dbdbd39 to d7d3d8b Compare February 8, 2026 14:26
@saghul saghul marked this pull request as ready for review February 8, 2026 14:38
@saghul saghul force-pushed the new-streams-api branch 3 times, most recently from c08de5b to 6142b21 Compare February 9, 2026 10:32
@saghul saghul changed the title streams: move stream logic to JS WebStreams all the things Feb 9, 2026
@saghul saghul marked this pull request as draft February 9, 2026 11:12
@saghul saghul force-pushed the new-streams-api branch 2 times, most recently from 83bddf3 to 2aba13c Compare February 9, 2026 14:09
Keep the native side as callbacks, as thin wrappers over libuv
abstractions.

This is in preparation of introducing Web Streams all across.
@saghul saghul marked this pull request as ready for review February 10, 2026 09:43
@saghul saghul merged commit 545d66e into master Feb 10, 2026
19 checks passed
@saghul saghul deleted the new-streams-api branch February 10, 2026 09:53
@ldeninski
Copy link
Copy Markdown
Contributor

ldeninski commented Feb 10, 2026

@saghul after this change all printf calls in WebAssembly are flushed before all of the console.logs. The only way to interleave these is to go async await wait() after every console.log call. Is there a way to flush the stdout stream synchronously? On a positive note this change makes calls to printf from WebAssembly to not need fflush(stdout) after every call to see 😄 . Before this change printfs were lost on script exit if you do not call fflush(stdout) OR all printfs were dumped partially at the end.. right before exit().

Also this is what happens in tjs

> console.log(tjs.stdout)
TypeError: This stream has already been locked for exclusive writing by another writer
    at WritableStreamDefaultWriter (polyfills.js:29:40413)
    at yt (polyfills.js:29:37351)
    at getWriter (polyfills.js:29:37318)
    at getStdoutWriter (polyfills.js:28:1289)
    at printer (polyfills.js:29:58)
    at _printer (polyfills.js:22:794)
    at Logger (polyfills.js:22:867)
    at <anonymous> (polyfills.js:28:1050)
    at <eval> (<evalScript>:1:12)
    at evalScript (native)
> tjs.stdout.getWriter()
TypeError: This stream has already been locked for exclusive writing by another writer
    at WritableStreamDefaultWriter (polyfills.js:29:40413)
    at yt (polyfills.js:29:37351)
    at getWriter (polyfills.js:29:37318)
    at <eval> (<evalScript>:1:11)
    at evalScript (native)
    at evalScript (run-repl.js:1:1822)
    at try (native)
    at eval_and_print (run-repl.js:32:191)
    at handle_cmd (run-repl.js:32:84)
    at readline_handle_cmd (run-repl.js:31:107)

@saghul
Copy link
Copy Markdown
Owner Author

saghul commented Feb 10, 2026

I'm considering replacing console.log's implementation with just fwrite + fflush. It has its drawbacks, but maybe it's for the best...

Can you give me a WASM example?

@ldeninski
Copy link
Copy Markdown
Contributor

ldeninski commented Feb 10, 2026

I'm considering replacing console.log's implementation with just fwrite + fflush. It has its drawbacks, but maybe it's for the best...

Can you give me a WASM example?

Sure:

test.c

#include "stdio.h"

__attribute__((visibility("default"))) void print_from_wasm(void) {
  printf("Print from WASM\n");
  fflush(stdout); // this is NOT needed any more
}

compile with clang --target=wasm32-wasi test.c -o test.wasm use wasi-sdk from here https://github.com/WebAssembly/wasi-sdk

test:js

const bin = await tjs.readFile('test.wasm');
const mod = new WebAssembly.Module(bin);
const inst = new WebAssembly.Instance(mod);

console.log('console.log before print_from_wasm');
inst.exports.print_from_wasm();
console.log('console.log after print_from_wasm');

This is the result for me:

14:47 $ tjs run src/examples/test.js 
Print from WASM
console.log before print_from_wasm
console.log after print_from_wasm

@saghul
Copy link
Copy Markdown
Owner Author

saghul commented Feb 10, 2026

Thanks!

@saghul
Copy link
Copy Markdown
Owner Author

saghul commented Feb 10, 2026

Can you give #774 a try?

@ldeninski
Copy link
Copy Markdown
Contributor

Can you give #774 a try?

That looks correct now :)

16:06 $ ../txiki.js/build/tjs run src/examples/test.js 
console.log before print_from_wasm
Print from WASM
console.log after print_from_wasm

@saghul
Copy link
Copy Markdown
Owner Author

saghul commented Feb 10, 2026

Alright, merged. Thanks for taking a look! This was driving me nuts, I'm happy with the result now :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants