Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web Serial binding #2271

Open
jaz303 opened this issue Jun 16, 2021 · 15 comments
Open

Web Serial binding #2271

jaz303 opened this issue Jun 16, 2021 · 15 comments

Comments

@jaz303
Copy link

jaz303 commented Jun 16, 2021

💥 Proposal

What feature you'd like to see

Hello! I've been working on a Web Serial binding for node-serialport and would like gauge interest in getting it merged into the official repo. The current status of the project is that it is working with a simple echo client, and all methods except flush() are implemented.

Motivation

A unified interface to access serial ports between node.js and the web allows code to be shared between CLI applications and web GUIs that communicate with serial devices. My specific use-case is allowing my port of the SAM-BA bootloader client to be deployed on the web.

I believe implementing a Web Serial binding for node-serialport is preferable to the reverse approach of adapting node-serialport to work with WHATWG Streams due to the relative simplicity of the Node streams interface, and the slow uptake of WHATWG streams within Node.

Pitch

Current usage:

const SerialPort = require('@serialport/stream');
SerialPort.Binding = require('web-serial-binding');

// Get serial port reference from browser
const nativePort = await navigator.serial.requestPort();

// Create the port. We pass a serial port object rather than a string path
// but there's no type checking in the SerialPort internals to it's all good :)
const port = new SerialPort(nativePort, {baudRate: 115200});

A final implementation would ideally detect a browser environment and set the binding automatically.

I've deliberately left the acquisition of the serial port (navigator.serial.requestPort()) out of scope of the binding as it's web specific and should be dealt with in the application's own platform abstraction. The static list() method remains, and returns a list of ports already visible to the browser.

@reconbot
Copy link
Member

reconbot commented Jun 16, 2021

💯 incredibly interested. I think your design decisions are pretty sound too.

@jaz303
Copy link
Author

jaz303 commented Jun 17, 2021

Cool, good to hear, I'll begin working on a PR.

How do you see the package hierarchy being organised? I was thinking of a bindings package, plus maybe a @serialport/web-serial package that explicitly configures SerialPort with the web binding - this would allow folk to use the package without forcing them to compile native bindings. The core package would also detect navigator.serial and, if present, default to the web binding.

Thoughts here much appreciated.

@reconbot
Copy link
Member

Let's start with @serialport/bindings-web and I like your idea of a web only package. Would it need to have a slightly different api than the main package? (Eg, an async constructor, list would work differently maybe?)

I've had an idea around changing the api of the bindings that actually might make it a little easier to get it into the main package. (I'm on mobile so it's hard to find the issue, bindings v2 or something) But I think once we have a working bindings package we can figure that out.

@reconbot
Copy link
Member

@jacobrosenthal thoughts on donating the browser-serialport npm package to this effort?

@monteslu you'll want to know about this =)

@GazHank
Copy link
Contributor

GazHank commented Jun 17, 2021

Here are links to some potentially associated "issues", in case it helps:

@reconbot
Copy link
Member

reconbot commented Jul 5, 2021

@jaz303 happy to help on this whenever you're ready

@frank-dspeed
Copy link
Contributor

i was working on the same thing and got the conclusion that it adds zero benefits for all cases that i spotted.

the main problem is requestPort waits for user input while nodejs does not need to do so

@reconbot
Copy link
Member

reconbot commented Jul 5, 2021

There's a lot of code that isn't getting the port that would benefit from taking a web serial source. You're not going to have an isomorphic app but you will have isomorphic libraries.

@frank-dspeed
Copy link
Contributor

@reconbot i did not see that in any code that i got the only thing that was usefull was porting the SerialPort Event Emitter API to the Web that is what i did i turned the "while port.read()" WebAPI into a emitter with on Data. on End.

I do see nothing that we can improve inside this project.

The Main diff out of lib view is the web stream implementation which is already ported to nodejs.

https://www.npmjs.com/package/web-streams-polyfill.

to be more exact:
web-streams-polyfill/ponyfill/es6: a ponyfill targeting ES2015+ environments. Recommended for use in Node 6+ applications, or in web libraries supporting modern browsers.
web-streams-polyfill/ponyfill/es2018: a ponyfill targeting ES2018+ environments. Recommended for use in Node 10+ applications.

@Azq2
Copy link

Azq2 commented Apr 13, 2024

Yet another WebSerial bindings: https://github.com/Azq2/node-serialport-bindings-webserial

@frank-dspeed
Copy link
Contributor

Thats the wrong direction in general i guess.

Web Streams got nativ in nodejs now and do in fact replace the old node:streams api's

both got aligned to work via the iterateable @symbol

so in both versions webStreams and nodeStreams for of loops will do the trick

Readable and Writeable got exposed since node 19+ global without import same as in browser context. They are the webstream implementations also helpers got created and shipped to convert streams into both directions.

@Azq2
Copy link

Azq2 commented Apr 14, 2024

@frank-dspeed I think this is not directly relevant to WebSerial.
I think we need separate issue to discuss WebStreams/NodeStreams support in the node-serialport.

In this issue we just want binding which allows us to use serial ports both in browsers and Node.js without great changes in the code.
And don't care how that is implemented inside.


@reconbot What about official webserial bindings? I think the time has come :)

@cjihrig
Copy link

cjihrig commented Apr 14, 2024

What about official webserial bindings?

FWIW, I started working on this a few years ago but ran into some blockers. See this discussion. I'd be happy to have that work revived.

@reconbot
Copy link
Member

It's still just as good as an idea

@Azq2
Copy link

Azq2 commented Nov 25, 2024

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

No branches or pull requests

6 participants