-
Notifications
You must be signed in to change notification settings - Fork 64
Update WebIDL and modify documentation to fit new "node.js-like" style #1800
Conversation
be syntactically correct and to follow the new style of buffer.md. Added a new file that explains some of the differences between WebIDL and Javascript.
Some changes to a few .md files to get feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reviewed about 2/3 so far but will try to get back to it tomorrow.
docs/aio.md
Outdated
This IDL provides an overview of the interface; see below for | ||
documentation of specific API functions. Click | ||
[here](Notes_on_WebIDL.md) for an explanation of zephyr.js' WebIDL | ||
conventions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please replace zephyr.js' with ZJS. The repo is zephyr.js
for historical reasons but that's not the name of the project.
And this is not required, but I prefer to make links be noun phrases describing what you're going to find, so I'd rather see "ZJS WebIDL conventions" be what is linked, which would require some rephrasing.
Same comment on repeated instances of this text below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
docs/aio.md
Outdated
Use the AIOPin object returned to read values from the pin. | ||
|
||
### AIOPin.read | ||
Returns an AIOPin object that be used to read values from the pin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that may be used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
docs/aio.md
Outdated
|
||
### AIOPin.readAsync | ||
### pin.readAsync(ReadCallback) | ||
* 'ReadCallback' *callback* User-provided callback function that takes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If callback is like a type and the variable name is ReadCallback
, let's call it readCallback
instead to match case in other arguments. (I'm a little confused. :D)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'll respond here; push the explanation to the other places it applies:
I inconsistently read the Buffer documentation and just got this wrong.
I've now edited the documents to fit the following rules (which match the examples in the WebIDL spec):
Variable names are camelCase, starting with a lower-case letter.
Type names are UpperCase.
|
||
Closes the AIOPin. Once it is closed, all event handlers registered will no | ||
Closes the AIOPin. Once it is closed, all registered event handlers will no |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice English / voice edits - thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm as human as the next guy, so I make these errors, too.
I'm also as OCD as the next guy, so expect more of these... :-)
docs/ble.md
Outdated
}; | ||
|
||
callback ReadCallback = void (unsigned long offset, | ||
FulfillReadCallback fulfillreadcallback); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is why I'm getting confused - here FulfillReadCallback
is treated like a type. So maybe in my earlier comment ReadCallback
was the "type" and the variable should just be callback
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As many ex-girlfriends have said to me: it's not you, it's me. :-)
The confounding inconsistency has been fixed (see above comment for more).
docs/ble.md
Outdated
that will direct users to the given URL. At that URL they might be | ||
able to interact with the advertising device somehow. | ||
|
||
Advertises the name of the device. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name and url
url is really the interesting bit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Also please fix the trailing whitespace issues here: https://travis-ci.org/intel/zephyr.js/jobs/334508966 |
docs/Notes_on_WebIDL.md
Outdated
API should be considered correct -- please report discrepancies as | ||
soon as possible. | ||
|
||
Although both WebIDL and Javascript are aimed at web applications, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JavaScript
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
interface AIO { | ||
AIOPin open(AIOInit init); | ||
}; | ||
|
||
dictionary AIOInit { | ||
unsigned long pin; | ||
(unsigned long or string) pin; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many many web devs are using TypeScript today, so I see more and more web frameworks actually documenting APIs using typescript. This is also useful because you can distribute the documentation as *.ts.d files which can be used in IDE's like VSCode to do autocompletion etc.
The above would be
interface AIOInit {
pin: number|string;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@t-harvey is working on a tool to generate code based on WebIDL. So for his purposes I think he needs WebIDL specifically, or is that itself up to suggestion? Earlier I suggested maybe we should move the WebIDL itself out to a .idl file. We could also have TypeScript in a .ts.d file or both... the only question would be how well would we actually maintain them. :)
If we could turn this into some automated testing that might alert us of mismatch (because of failures) and we'd be more likely to keep it synced correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We did have a existing PR that had typescript before #1572, but that was providing auto-completetions, and I haven't figure out how to import it into the ide without conflicting with other .ts.d files, so i had to close the PR, but we do have similar apis.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Geoff, I'd love to move the WebIDL to its own file and then just include it in the .md file -- but markdown doesn't seem to allow such a thing (correct me if I'm wrong). It's true that I could just have a link to a .idl file in the main page, but I tried that, and it doesn't look nearly as nice as having the WebIDL inline -- and I really like the streamlined API that WebIDL gives you in addition to the textual description; it's a lot like having a picture to reference.
Currently, I cut/paste the WebIDL out of the docs into their own .idl file and test them (which is why I missed the problem that @kenchris caught).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that cut and pasting was part of my motivation. But yes I was thinking of just having a link to it. Hopefully by standardizing the way the WebIDL appears you can write a script to cut and paste automatically. I don't have any reason to force them out into .idl
files right now, but eventually that might be best. One thing about the "Node.js" style is the functions are all listed again in the table of contents so it's a bit repetitive.
|
||
```javascript | ||
// require returns a BLE object | ||
// var ble = require('ble'); | ||
|
||
[NoInterfaceObject] | ||
[ReturnFromRequire] | ||
interface BLE: EventEmitter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this would be
class BLE extends EventEmitter {
disconnect(address: string): void;
startAdvertising(name: string, uuids: string[], url: string): void;
stopAdvertising(): void;
setServices(services: PrimaryService[]) void;
newPrimaryService(init: PrimarySeviceInit): PrimaryService;
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is very JS like but has a bit of extra info, like types, readonly etc
docs/ble.md
Outdated
callback WriteCallback = void (Buffer data, unsigned long offset, | ||
boolean withoutResponse, FulfillWriteCallback); | ||
boolean withoutResponse, | ||
FulfillWriteCallback fulfillwritecallback); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
really weird indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, sorry; if you ever see this again, it's b/c Emacs tabs have to be converted to spaces for the Markdown to line up correctly.
octet readUInt8(optional unsigned long offset = 0); | ||
short readUInt16BE(optional unsigned long offset = 0); | ||
short readUInt16LE(optional unsigned long offset = 0); | ||
long readUInt32BE(optional unsigned long offset = 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in TS: readUInt32BE(offset: number = 0): number
docs/buffer.md
Outdated
unsigned long copy(Buffer target, optional unsigned long targetStart = 0, | ||
optional unsigned long sourceStart = 0, | ||
optional unsigned long sourceEnd = this.length); | ||
this fill((string or Buffer or long) value, optional long offset = 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can not add "this" in an API. and same with this.length.
Could be Buffer fill(value, offset, end = -1)
then you enterpret -1 to measure yourself or so
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@t-harvey, does the WebIDL you've added/corrected work with your tool, or is that still being developed?
If we go to the trouble of making the WebIDL correct, I'd like to make sure we keep it that way by validating it with CI somehow. Could your tool or something else check for at least basic validity?
``` | ||
|
||
API Documentation | ||
----------------- | ||
BLE-supported Events |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The term "BLE-supported" doesn't make sense to me. See how they list events in the Node dgram API - they go in the same "Class: xyz" section as the APIs below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@grgustaf -- my tool could easily(!) be adapted to check for WebIDL syntax. In my copious spare time, I'll gen up a simple app -- but I'll need someone who knows (useful) things to put it into the automatic testing...
...If that's what we want; I had sort of just planned on periodically running my actual tool over the code as a natural result of my testing/development and keeping the WebIDL up to date that way...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In re: events (i.e., "ble-supported" events)
The problem here is that each event isn't really part of the BLE object; in some ways, it's bifurcating the documentation: on one hand, most of the docs describe the interface the user sees/manipulates, etc. -- but with events (and maybe other things?), it's really addressing concerns of the guys implementing the underlying behavior. I don't know that the text describing events even belongs in this documentation...(?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be a misunderstanding? Those events are indeed part of the BLE object and the ZJS user can (and needs to) register functions to listen for them with the .on() method. For example, see this BLE sample.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The on()
method comes in because BLE is an EventEmitter; perhaps this needs to be made more clear, but it does basically behave like Node now and this was an attempt to document things in the same way they do. Maybe we missed some connecting glue though. :)
|
||
### new Buffer(size) | ||
* `size` *integer* Length in bytes of the new buffer. | ||
|
||
The `size` argument specifies the length in bytes of the array that the Buffer | ||
represents. If a negative length is passed, a 0-length Buffer will be returned. | ||
If the size is too long and there is not enough available memory, an error will | ||
If there is not enough available memory to allocate the Buffer, an error will |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, thanks for these English improvements - nice to have more eyes on it!
interface AIO { | ||
AIOPin open(AIOInit init); | ||
}; | ||
|
||
dictionary AIOInit { | ||
unsigned long pin; | ||
(unsigned long or string) pin; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We did have a existing PR that had typescript before #1572, but that was providing auto-completetions, and I haven't figure out how to import it into the ide without conflicting with other .ts.d files, so i had to close the PR, but we do have similar apis.
Characteristic Characteristic(CharacteristicInit init); | ||
Descriptor Descriptor(DescriptorInit init); | ||
void setServices(PrimaryService[] services); | ||
PrimaryService newPrimaryService(PrimaryServiceInit init); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is newXXX the standard in webidl to declare a constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...no, I don't think there is a standard WebIDL way to declare a constructor of one object as a method of some other object.
...but given that that's what this was doing, I made up a consistent naming scheme and hoped it would suffice (it gets the idea across; I didn't explain it and you intuited its function!). As with almost anything I write, I'm not married to it and would welcome(!) better ideas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Web IDL please always refer to the editors draft - the stable one is very old: https://heycam.github.io/webidl/
PrimaryService newPrimaryService(PrimaryServiceInit init);
is pretty weird
In old fashioned JS (no class) the constructor is a function which has the same name as the object, ie.
function PrimaryService(PrimaryServiceInit init) {
this.name = init.name;
}
So in Web IDL you would just write it as
[Constructor(PrimaryServiceInit init), Exposed=Window]
interface PrimaryService {
};
Guys,
|
Just to give some comments. To generate bindings etc Web IDL is the way to go, that is what it is designed for and what browsers use. TypeScript definition files are super useful, even when not using TypeScript. Like in VSCode I can just add a comment like For external libraries you can include these .ts.d files like I have the following in package.json for projects using Web Bluetooth:
I think that offering the same would be quite nice. I guess it is probably doable to generate these ts.d files from Web IDL as well. I found a few related issues here: microsoft/TypeScript#3027 and microsoft/TypeScript-DOM-lib-generator#101 microsoft/TypeScript-DOM-lib-generator#227 https://github.com/SaschaNaz/webidl-serializer |
PrimaryService PrimaryService(PrimaryServiceInit init); | ||
Characteristic Characteristic(CharacteristicInit init); | ||
Descriptor Descriptor(DescriptorInit init); | ||
void setServices(PrimaryService[] services); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in Web IDL we don't use [], you will normally use sequence<PrimaryService>
or FrozenArray<PrimaryService>
depending on the exact use-case.
|
||
```javascript | ||
// require returns a BLE object | ||
// var ble = require('ble'); | ||
|
||
[NoInterfaceObject] | ||
[ReturnFromRequire] | ||
interface BLE: EventEmitter { | ||
void disconnect(string address); | ||
void startAdvertising(string name, string[] uuids, string url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also don't have strings in Web IDL, we have DOMString, ByteString and USVString. Thus here you probably want
startAdvertising(USVString name, sequence<DOMString>, USVString url)
interface Characteristic { | ||
attribute ReadCallback onReadRequest; | ||
attribute WriteCallback onWriteRequest; | ||
attribute SubscribeCallback onSubscribe; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very un-web like... should be onsubscribe
all lowercase plus these should be nullable.
attribute SubscribeCallback? onsubscribe
callback FulfillReadCallback = void (CharacteristicResult result, Buffer data); | ||
callback FulfillWriteCallback = void (CharacteristicResult result); | ||
callback FulfillSubscribeCallback = void (Buffer data); | ||
|
||
enum CharacteristicResult { "RESULT_SUCCESS", "RESULT_INVALID_OFFSET", "RESULT_INVALID_ATTRIBUTE_LENGTH", "RESULT_UNLIKELY_ERROR" } ; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When enumeration types are for strings (preferred today) then they should all be LOWER CASE and with HYPHEN between.. not underscore.
enum CharacteristicResult { "success", "invalid-offset"... }
optional long length = this.length-offset, | ||
optional string encoding = "utf8"); | ||
long writeUInt8(octet value, unsigned long offset); | ||
long writeUInt16BE(unsigned short value, unsigned long offset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not optional unsigned long offset = 0 here?
Part of the detail-oriented nature of my comments was that I didn't notice your comments about requesting just general discussion the first time I read it. Details are what we normally do around here. :) But yes, absolutely editing the documentation is okay. We try to keep them up to date but that's not always in the forefront of our minds. And yes, if you want correct WebIDL then by all means we're willing to accept improvements. We'll try to understand the changes you're making so that we can make new stuff better out of the gate and maintain things properly. We haven't cared to date because basically it just served as a documentation format; specific correctness wasn't important and the couple times I looked into the spec didn't overwhelm me with a desire to read the whole thing. :) |
Could still consider this, but closing for lack of progress... If we reopen I'd probably want to move webidl out into separate files like I proposed at some point, though. |
Hi -- this is a test edit to spark discussion; please don't accept this pull request!
After a short discussion (#1759), I edited three different .md files in the documentation to get feedback.
The thrust of the changes is that I want to fix the WebIDL to make it not only syntactically correct, but also to make it match the textual description of each api.
However, since Geoff Gustafson updated Buffer.md to be more like node.js documentation, I also changed a couple of the files to match this style.
I propose making similar changes across the documentation, but I would like to limit my commitment to what I've done here -- specifically, I want to make the WebIDL match the description, but my manager would prefer that correctness of the documentation itself be left to other folks :-). For an example of this, see ble.md, where I left the description of the Characteristic API blank (seach for "TODO") (the 2nd TODO was already in the documentation).
Thanks for considering this!
Tim