-
Notifications
You must be signed in to change notification settings - Fork 28
API for next PlugFest (Prague 2018) #82
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
Comments
#78 diffused a bit. Let's try to keep the first post here sticky and update it with our latest view to be eventually put into the next Working Draft. Please comment with change requests. |
Please don't create issues just for hopping discussion from one issue to the other. We should continue #78 as there are unanswered questions there, with the context being there, not here. I have fixed some typos/bugs in the proposal. Notes, questions:
|
Propose an optional field
Without it we end up with autogenerated prefixes such as Shall we add this to the proposal? If there is consensus I can do so and remove this comment to avoid confusion... |
You could set up a temporary document containing the API definitions. #78 was not suitable during TPAC to understand what is the latest proposal. When the document is in place, you can close this issue. |
Added |
I would like to clarify the difference and need of
currently described in Let's use a snippet of an example TD which shows the need for representing
Consequently we need the same |
A possible "TypeSystem" definition for |
Minor comment. I assume |
To my understanding, |
The API currently lacks security aspects. We might need to align with Security in TD. |
IMHO the API itself should be agnostic of security aspects. It is the algorithm specifications and implementation/runtime that should address and encapsulate security (e.g. secure contexts, required permissions, access policies etc). At API (client code) level we want transparent interoperability between different security realms. Provisioning process (out of WG scope) and the runtime/API implementation (in scope) should take care of security setup and enforcement. What comes to the Scripting spec, the only thing to make sure is that the algorithms later described in the spec do specify the mechanisms runtimes should support in order to enable security setup (by an external tool specific to the solution) and enforcement. |
W.r.t. security I mean that we need at least a way to provide/define security requirements so that a |
* remove url attribute * rename description to td * rename getProperty to readProperty * rename setProperty to writeProperty * rename observe to getObservable and simplify parameters * remove listeners
Update ConsumedThing according to w3c/wot-scripting-api#82 * remove url attribute * rename description to td * rename getProperty to readProperty * rename setProperty to writeProperty * rename observe to getObservable and simplify parameters * remove listeners
Regarding security, I have created an issue in the security TF repo and cross-referenced it to this one: RESOLUTION: As discussed in the meeting on Dec 18, security data, like protocol bindings, need to be provided when the Thing is provisioned, eg when the Thing runtime is set up. The scripting API only deals with actions taken from "inside" a Thing, and so this setup is out of scope. However, for practical reasons, we do need to have an implementation that allows this information to be specified. Therefore, the node-wot API should be extended to support the definition of security metadata during setup, and this part of the API should be documented, but it should be made clear that this part of the node-wot API is non-normative. |
Two more comments:
|
The signature of Question: Are we ok with this limitation ? |
+1 to merge ThingBuilder into ExposedThing |
We should look into the naming discussions in whatwg/dom#544 (shared by Zoltan). |
Updated example in first comment with results from Scripting API call on 18 Dec 2017. |
|
Hi @zolkis, Maybe some feedback provided during the call w.r.t. 2 The implementation functionality with or without "mixin" is essentially the same. Moreover, I think support for "mixin" is restricted to some languages. The feedback during the call was also that given the original Anyhow, let's put this topic on the agenda for next call again. |
When you implement the API, in TS there is no ThingBuilder visible anywhere, you just implement all props/functions in it as it was part of ExposedThing. But in the spec, with WebIDL expression, having a mixin delineates the building functionality more clearly. So, there is no ThingBuilder, it is just one way to declare a group of functionality in WebIDL. |
Making a separate comment on the following proposal (to be discussed on the call).
Changes:
interface ConsumedThing {
readonly attribute DOMString name;
readonly attribute ThingDescription td;
Promise<any> readProperty(DOMString name); // aligned with 'writable'
Promise<void> writeProperty(DOMString name, any value); // aligned with 'writable'
Promise<any> invokeAction(DOMString name, any parameters);
// Observable getObservable(DOMString name);
Observable onEvent(DOMString name); // subscribe to events
Observable onPropertyChange(DOMString name); // subscribe to property change
};
interface ExposedThing: ConsumedThing {
Promise<void> start(); // useful to make async or counter-productive?
Promise<void> stop();
Promise<void> register(USVString url); // convenience for Thing Directory
Promise<void> unregister(USVString url); // convenience for Thing Directory
Promise<void> emitEvent(DOMString eventName, any payload);
DynamicThing edit(); // locks the object for editing
};
interface DynamicThing: ExposedThing {
ThingBuilder addProperty(ThingPropertyInit property); // throws on error
ThingBuilder removeProperty(DOMString name); // throws on error
ThingBuilder addAction(ThingActionInit action); // throws on error
ThingBuilder removeAction(DOMString name); // throws on error
ThingBuilder addEvent(ThingEventInit event); // throws on error
ThingBuilder removeEvent(DOMString name); // throws on error
void lock(); // finish editing the ExposedThing object
}; One way to use it: try {
thing = wot.expose({ name: "newThing"});
thing.edit()
.addProperty(...)
.addAction(...)
.addEvent(...);
.lock(); // may also do re-registrations as well
} catch(e) {
} |
As discussed in the call, I have updated the first (sticky) comments with:
If we want to keep the edit lock mechanism, the editing functions need to be accessible only during that transaction. So IMHO we should keep the ThingBuilder interface (as above), which is always tied to one instance (URL) of ExposedThing. But this version (outlined in the first comment) I used inline functions for editing and without the "state" property. If not in editing transactions, all editing methods will throw. @mkovatsc @danielpeintner @knimura please take a look again at the previous comment, I edited for a simpler interface. |
As discussed on today's call, removed the As a record,
Also, it was requested to keep the current way of exposing existing interactions explicitly and separately, e.g. not as a generic We will need to specify mechanisms for
|
Signed-off-by: Zoltan Kis <[email protected]>
As I mentioned in the call, I would see value in splitting the API into two sections or documents, using interface WoT {
Observable<ConsumedThing> discover(optional ThingFilter filter);
Promise<ThingDescription> fetchTD(USVString url);
ConsumedThing consume(ThingDescription td);
ExposedThing expose(dictionary init); // ThingTemplate
};
typedef USVString ThingDescription;
interface ConsumedThing {
readonly attribute DOMString name;
readonly attribute ThingDescription td;
Promise<any> readProperty(DOMString name); // aligned with 'writable'
Promise<void> writeProperty(DOMString name, any value); // aligned with 'writable'
Promise<any> invokeAction(DOMString name, any parameters);
Observable onEvent(DOMString name); // subscribe to events
Observable onPropertyChange(DOMString name); // subscribe to property change
Observable onTDChange(); // subscribe to Thing Description change
};
callback ThingEventListener = void (ThingEvent event);
callback PropertyChangeListener = void (PropertyChangeEvent change);
callback TDChangeListener = void (TDChangeEvent td);
interface ExposedThing: ConsumedThing {
Promise<void> start(); // useful to make async or counter-productive?
Promise<void> stop();
Promise<void> register(USVString url); // convenience for Thing Directory
Promise<void> unregister(USVString url); // convenience for Thing Directory
Promise<void> emitEvent(DOMString eventName, any payload);
void setActionHandler(DOMString actionName, Function action);
void setPropertyReadHandler(DOMString propertyName, PropertyReadHandler readHandler);
void setPropertyWriteHandler(DOMString propertyName, PropertyWriteHandler readHandler);
};
callback PropertyReadHandler = any (DOMString propertyName);
callback PropertyWriteHandler = void (DOMString propertyName, any value); And the following would be either in the same document in a different section/chapter, or in a separate document, depending how long the total document gets when algorithm descriptions will be added. The following is just a vague set, but it's pretty big in itself. partial interface ExposedThing {
void addProperty(ThingPropertyInit property); // throws on error
void removeProperty(DOMString name); // throws on error
void addAction(ThingActionInit action); // throws on error
void removeAction(DOMString name); // throws on error
void addEvent(ThingEventInit event); // throws on error
void removeEvent(DOMString name); // throws on error
};
// A full ThingTemplate aligned with ThingDescription requires pure JSON serialization of TD!
dictionary ThingTemplate {
DOMString name;
sequence<SemanticType>? semanticTypes;
sequence<SemanticMetadata>? metadata;
}
dictionary SemanticType {
DOMString name;
USVString context;
DOMString prefix;
};
dictionary SemanticMetadata {
SemanticType type;
any value;
};
dictionary ThingPropertyInit {
DOMString name;
ValueDefinition value;
boolean? writable = false;
boolean? observable = false;
sequence<SemanticType>? semanticTypes;
sequence<SemanticMetadata>? metadata;
};
dictionary ThingActionInit {
DOMString name;
sequence<ValueDefinition> inputTypes;
ValueDefinition outputType;
sequence<SemanticType>? semanticTypes;
sequence<SemanticMetadata>? metadata ;
};
dictionary ThingEventInit {
DOMString name;
ValueDefinition value; // data carried by the event
sequence<SemanticType>? semanticTypes = [];
sequence<SemanticMetadata>? metadata = [];
};
typedef DOMString ValueType;
interface ValueDefinition {
readonly attribute ValueType type;
readonly attribute any defaultValue;
readonly attribute any min;
readonly attribute any max;
}; The
|
Hi @zolkis before discussing the splitting further (I am not sure that we need it) I think we need to agree on the overall concept again. In your latest comments you introduce callback handlers such as I don't think those are needed. The according handlers are to be passed in |
At this time we should only split these parts into different chapters/sections in the same document. When we add the algorithms, we'll see how big the document gets and whether it will be needed to move the TD generation part out into another document (part of the same WG deliverable).
We have discussed in yesterday's scripting call that we need a way to bind interaction handler scripts to interactions described in the TD. One opposing argument (from @mkovatsc) against splitting was exactly how do we detach and specify these handlers when we create the TD by a script. At least we seem to agree that we do need the handlers. So yes, they are needed, and they are there even now. However, currently they are passed in init dictionary members, which is a no-no (besides, they are not spec'd correctly there). They should be moved out from init dictionaries to be explicitly visible functionality at the |
…o onEvent, onPropertyChange, and onTDChange
Addressed by #86. |
Uh oh!
There was an error while loading. Please reload this page.
The text was updated successfully, but these errors were encountered: