Check the comments below on how we arrived to this variant.
typedef DOMString PropertyFragment; // serialized TD Property
// includes InteractionPattern and DataSchema
// InteractionPattern contains: title, titles, description, descriptions, forms, security, uriVariables
// DataSchema contains: type, unit, enum, oneOf, const, readOnly, writeOnly
// repeated (from InteractionPattern): [ title, titles, description, descriptions ]
typedef DOMString ActionFragment; // serialized TD Action
// includes InteractionPattern + input, output, safe, idempotent
typedef DOMString EventFragment; // serialized TD Event
// includes InteractionPattern + data, subscription, cancellation
[Constructor(PropertyFragment init)]
interface ThingProperty: EventTarget {
Promise<any> read();
Promise<void> write(any value);
readonly attribute object metadata; // get TD members
attribute EventHandler onchange; // simple event
};
[Constructor(ActionFragment init)]
interface ThingAction {
Promise<any> invoke(optional any parameters);
readonly attribute object metadata; // get TD members
};
[Constructor(EventFragment init)]
interface ThingEvent: EventTarget {
readonly attribute object metadata; // get TD members
attribute EventHandler onnotification;
};
typedef DOMString ThingFragment; // serialized Thing Description
[Constructor(optional ThingFragment init)]
interface ConsumedThing: EventTarget {
Promise<void> updateMetadata(USVString url); // former fetch()
readonly attribute object metadata; // get TD members
// expose the WoT interactions explicitly
ThingProperty getProperty(DOMString name);
ThingAction getAction(DOMString name);
ThingEvent getEvent(DOMString name);
attribute EventHandler onchange; // simple event for TD change
};
typedef (ThingFragment or ConsumedThing) ThingModel;
typedef (PropertyFragment or ThingProperty) PropertyModel;
typedef (ActionFragment or ThingAction) ActionModel;
typedef (EventFragment or ThingEvent) EventModel;
[Constructor(ThingModel init)]
interface ExposedThing: ConsumedThing {
ExposedThing addProperty(DOMString name, PropertyModel property, optional any initValue);
ExposedThing setPropertyReadHandler(DOMString name, PropertyReadHandler readHandler);
ExposedThing setPropertyWriteHandler(DOMString name, PropertyWriteHandler writeHandler);
ExposedThing removeProperty(DOMString name);
ExposedThing addAction(DOMString name, ActionModel init, ActionHandler action);
ExposedThing removeAction(DOMString name);
ExposedThing setActionHandler(DOMString name, ActionHandler action);
ExposedThing addEvent(DOMString name, EventModel event);
ExposedThing removeEvent(DOMString name);
void emitEvent(DOMString name, any data);
Promise<void> expose();
Promise<void> destroy();
Promise<void> register(USVString directory);
Promise<void> unregister(USVString directory);
};
callback PropertyReadHandler = Promise<any>();
callback PropertyWriteHandler = Promise<void>(any value);
callback ActionHandler = Promise<any>(any parameters);
dictionary ThingFilter {
(DiscoveryMethod or DOMString) method = "any";
USVString? url;
USVString? query;
ThingFragment? fragment;
};
[Constructor(optional ThingFilter filter)]
interface ThingDiscovery: EventTarget {
void start();
void stop();
attribute EventHandler onfound;
attribute EventHandler onerror;
attribute EventHandler oncomplete;
};
interface WOT {
Promise<void> start(optional WotOptions options);
void stop();
Promise<ThingDescription> fetch(USVString url);
};
Web IDL of the current Working Draft: https://www.w3.org/TR/wot-scripting-api/
Let's redesign the interfaces one by one, first the interactions (Property, Action, Event).
Main question: how to handle TD and TD fragments:
=> we need to define these objects in prose (but then it's already done in the TD spec).
For now let's explore option 1: TD and TD fragments come as DOMString, they are used for initializing ThingProperty, ThingAction, ThingEvent and their members can be accessed by explicit methods as metadata.
Note that we don't any more need Observer pattern, nor ExposedEvent.