The Web of Things (WoT) provides layered interoperability between Things by using the WoT Interfaces.

This specification describes a programming interface representing the WoT Interface that allows scripts run on a Thing to discover and consume (retrieve) other Things and to expose Things characterized by WoT Interactions, i.e. Properties, Actions and Events.

Scripting is an optional "convenience" building block in WoT and it is typically used in gateways that are able to run a WoT Runtime and script management, providing a convenient way to extend WoT support to new types of endpoints and implement WoT applications like Thing Directory.

Implementers need to be aware that this specification is considered unstable. Vendors interested in implementing this specification before it eventually reaches the Candidate Recommendation phase should subscribe to the [repository](https://github.com/w3c/wot-scripting-api) and take part in the discussions.

Please contribute to this draft using the GitHub Issue feature of the WoT Scripting API repository. For feedback on security and privacy considerations, please use the WoT Security and Privacy Issues.

Introduction

The overall WoT concepts are described in the [WoT Architecture](https://w3c.github.io/wot-architecture/) document. The Web of Things is made of entities (Things) that can describe their capabilities in a machine-interpretable format, the Thing Description (TD) and expose these capabilities through the WoT Interface. Support for scripting is optional for WoT devices.

By consuming a TD, a client Thing creates a runtime resource model that allows accessing the Properties, Actions and Events exposed by the server Thing.

Exposing a Thing requires defining a Thing Description (TD) and instantiating a software stack needed to serve requests for accessing the exposed Properties, Actions and Events. This specification describes how to expose and consume Things by a script.

Typically scripts are meant to be used on devices able to provide resources (with a WoT interface) for managing (installing, updating, running) scripts, such as bridges or gateways that expose and control simpler devices as WoT Things.

This specification does not make assumptions on how the WoT Runtime handles and runs scripts, including single or multiple tenancy, script deployment and lifecycle management. The API already supports the generic mechanisms that make it possible to implement script management, for instance by exposing a manager Thing whose Actions (action handlers) implement script lifecycle management operations.

For an introduction on how scripts could be used in Web of Things, check the [Primer](https://w3c.github.io/wot-scripting-api/primer) document. For some background on API design decisions check the [Rationale](https://w3c.github.io/wot-scripting-api/rationale) document.

Use Cases

The following scripting use cases are supported in this specification:

Discovery

Consuming a Thing

Exposing a Thing

The WoT object

The WoT object is the API entry point and it is exposed by an implementation of the WoT Runtime. The WoT object does not expose properties, only methods for discovering, consuming and exposing a Thing.

Browser implementations SHOULD use a namespace object such as `wot`, and [Node.js](https://nodejs.org/en/)-like runtimes MAY provide the API object through the [`require()`](https://nodejs.org/api/modules.html) or [`import`](http://www.ecma-international.org/ecma-262/6.0/#sec-imports) mechanism.

      // [SecureContext]
      // [NamespaceObject]
      interface WoT {
        Observable<ConsumedThing> discover(optional ThingFilter filter);
        Promise<ThingDescription> fetch(USVString url);
        ConsumedThing consume(ThingDescription td);
        ExposedThing produce(ThingModel model);
      };
      typedef USVString ThingDescription;
      typedef (ThingTemplate or ThingDescription) ThingModel;
    

The algorithms for the WoT methods will be specified later, including error handling and security considerations.

The discover() method

Starts the discovery process that will provide ConsumedThing objects that match the optional argument ThingFilter. When the argument is not provided, starts the widest discovery the Thing Description and Protocol Bindings allow and support. Returns an [Observable](https://github.com/tc39/proposal-observable) object that can be subscribed to and unsubscribed from.

The DiscoveryMethod enumeration

          typedef DOMString DiscoveryMethod;
        

DiscoveryMethod represents the discovery type to be used:

  • "any" does not provide any restriction
  • "local" for discovering Things defined in the same device
  • "nearby" for discovering Things nearby the device, e.g. by Bluetooth or NFC
  • "directory" for discovery based on a service provided by a directory or repository of Things
  • "broadcast" for an open ended discovery based on sending a request to a broadcast address
  • "other" for a proprietary method defined by the solution.

The ThingFilter dictionary

The ThingFilter dictionary that represents the constraints for discovering Things as key-value pairs.

          dictionary ThingFilter {
            DiscoveryMethod method = "any";
            USVString url;
            USVString query;
            sequence<Dictionary> constraints;
          };
        

The method property represents the discovery type that should be used in the discovery process. The possible values are defined by the DiscoveryMethod enumeration that can be extended by string values defined by solutions (with no guarantee of interoperability).

The DiscoveryMethod enumeration can be extended by the Thing Description with values that are not specified here. This extensibility of DiscoveryMethod by proprietary or private methods is a working assumption until consensus is formed and may be removed later.

The url property represents additional information for the discovery method, such as the URL of the target entity serving the discovery request, such as a Thing Directory or a Thing.

The query property represents a query string accepted by the implementation, for instance a SPARQL query.

The constraints property represents additional information for the discovery method in the form of a list of sets of property-value pairs (dictionaries). The list elements (dictionaries) are in OR relationship, and within a constraint dictionary the key-value pairs are in AND relationship. Implementations SHOULD make the following mapping from the constraint dictionaries to SemanticAnnotations: for each property-value pair in a constraint dictionary,

  • Each property name in the constraint dictionary SHOULD match the either the `name` property of a defined SemanticType on the target Thing object, or the name of a Property on the target Thing.
  • When the name matches, the values are compared. If the values match, the constraint is matched.

Constraints are experimental feature, implementations are not required to support them.

Semantic annotations need revisiting in order to simplify their representation. In the [[WOT-TD]] specification they represent the `@type` construct. At the moment only `@context`, `@type` and `@id` constructs are used in the TD.

The fetch() method

Accepts an url argument and returns a Promise that resolves with a ThingDescription.

The ThingDescription type

Representation of the Thing Description, standardized in the [Wot Things Description](https://w3c.github.io/wot-thing-description/) specification.

In this version of the API, Thing Descriptions are represented as opaque strings, denoting a serialized form, for instance JSON or JSON-LD. See [Issue 38](https://github.com/w3c/wot-scripting-api/issues/38) and [Issue 45](https://github.com/w3c/wot-scripting-api/issues/45).

The consume() method

Accepts an td argument of type ThingDescription and returns a ConsumedThing object instantiated based on that description.

The produce() method

Accepts a model argument of type ThingModel and returns an ExposedThing object, locally created based on the provided initialization parameters. An ExposedThing can be created in the following ways:

  1. from an initial model (including a user given name and semantic annotations), then adding properties, actions, events and request handlers;
  2. from a Thing Description (possibly of a ConsumedThing object), then adding request handlers.

The ThingModel type

A Thing model is used for producing a new ExposedThing and can be either a ThingTemplate, or a ThingDescription.

The SemanticAnnotations dictionary

A dictionary that provides the semantic types and semantic metadata.

        dictionary SemanticAnnotations {
            sequence<SemanticType> semanticType;
            sequence<SemanticMetadata> metadata;
        };
      

The semanticType property denotes a list of SemanticType objects that define the semantic types that can be used in semantic metadata type-value pairs.

The metadata property denotes a list of SemanticMetadata objects (type-value pairs).

The SemanticType dictionary

        dictionary SemanticType {
            required DOMString name;
            required USVString context;
            DOMString prefix;
        };
      

Represents a semantic type annotation, containing a name, a context and a prefix.

Semantic type examples to be added.

The SemanticMetadata dictionary

        dictionary SemanticMetadata {
            SemanticType type;
            any          value;
        };
      

The SemanticMetadata dictionary describes a pair of semantic type and value:

The ThingTemplate dictionary

A Thing Template is a dictionary that provides a user given name, and the semantic types and semantic metadata attached to the ExposedThing Thing Description's root level.

        dictionary ThingTemplate: SemanticAnnotations {
            required DOMString name;
        };
      

The ThingTemplate dictionary extends SemanticAnnotations and contains properties to initialize a Thing:

Support for configuration and security data might be added later.

Examples

        let discoveryFilter = {
          method: "directory",
          url: "http://directory.wotservice.org"
        };
        let subscription = wot.discover(discoveryFilter).subscribe(
          thing => { console.log("Found Thing " + thing.name); },
          error => { console.log("Discovery finished because an error: " + error.message); },
          () => { console.log("Discovery finished successfully");}
        );
        setTimeout( () => {
            subscription.unsubscribe();
            console.log("Discovery timeout");
          },
          5000);
      

Note that canceling a discovery (through `unsubscribe()`) may not be successful in all cases, for instance when discovery is based on open ended broadcast requests. However, once `unsubscribe()` has been called, implementations MUST suppress further event handling ( i.e. further discoveries and errors) on the Observable. Also, a discovery error may not mean the end of the discovery process. However, in order to respect Observable semantics (error always terminates processing), implementations MUST close or suppress further event handling on the Observable.

        let subscription = wot.discover({ method: "local" }).subscribe(
          thing => { console.log("Found local Thing " + thing.name); },
          error => { console.log("Discovery error: " + error.message); },
          () => { console.log("Discovery finished successfully");}
        );
      
        let subscription = wot.discover({ method: "local" }).subscribe({
          thing => { console.log("Found local Thing " + thing.name); },
          error: err => { console.log("Discovery error: " + err.message); },
          complete: () => { console.log("Discovery finished successfully");}
        });
      
        let subscription = wot.discover({
          method: "nearby",
          constraints: [{ protocol: "BLE-4.2" }, { protocol: "NFC"}]
        }).subscribe(
          thing => { console.log("Found nearby Thing " + thing.name); },
          error => { console.log("Discovery error: " + error.message); },
          () => { console.log("Discovery finished successfully");}
        );
      
        let subscription = wot.discover({
          method: "other",
          constraints: [{ solution: "XYZ123", key: "..."}]
        }).subscribe(
          thing => { console.log("Found Thing " + thing.name); },
          error => { console.log("Discovery error: " + error.message); },
          () => { console.log("Discovery finished successfully");}
        );
      

The ConsumedThing interface

The ConsumedThing interface is a client API for sending requests to servers in order to retrieve or update Properties, invoke Actions, and observe Properties and Events.

      interface ConsumedThing {
        readonly attribute DOMString name;
        ThingDescription getThingDescription();
        Promise<any> readProperty(DOMString name);
        Promise<void> writeProperty(DOMString name, any value);
        Promise<any> invokeAction(DOMString name, any parameters);
        Observable onPropertyChange(DOMString name);
        Observable onEvent(DOMString name);
        Observable onTDChange();
      };
    

ConsumedThing represents a local proxy object of the remote Thing.

The name property

The `name` property represents the name of the Thing as specified in the TD. In this version it is read only.

The getThingDescription() method

Returns the Thing Description of the Thing.

In this version, introspection based on TD is out of scope. Parsing and exposing Thing Descriptions is discussed in [Issue 38](https://github.com/w3c/wot-scripting-api/issues/38).

The readProperty() method

Takes the Property name as the name argument, then requests from the underlying platform and the Protocol Bindings to retrieve the Property on the remote Thing and return the result. Returns a Promise that resolves with the Property value or rejects with an Error.

The writeProperty() method

Takes the Property name as the name argument and the new value as the value argument, then requests from the underlying platform and the Protocol Bindings to update the Property on the remote Thing and return the result. Returns a Promise that resolves on success or rejects with an Error.

The invokeAction() method

Takes the Action name from the name argument and the list of parameters, then requests from the underlying platform and the Protocol Bindings to invoke the Action on the remote Thing and return the result. Returns a Promise that resolves with the return value or rejects with an Error.

The onPropertyChange() method

Returns an Observable for the Property specified in the name argument, allowing subscribing to and unsubscribing from notifications.

The callback function passed to the subscribe() method when invoked on the returned observer will receive the new property value each time it is changed.

The onEvent() method

Returns an Observable for the Event specified in the name argument, allowing subscribing to and unsubscribing from notifications.

The callback function passed to the subscribe() method when invoked on the returned observer will receive the event data each time the event is fired.

The onTDChange() method

Returns an Observable, allowing subscribing to and unsubscribing from notifications to the Thing Description.

The callback function passed to the subscribe() method when invoked on the returned observer will receive the new Thing Description each time it is changed.

Examples

Below a ConsumedThing interface example is given.

        try {
          let td = await wot.fetch("http://mmyservice.org/mySensor");
          let thing = wot.consume(td);
          console.log("Thing " + thing.name + " has been consumed.");
          let subscription = thing.onPropertyChange("temperature")
            .subscribe(function(value) {
              console.log("Temperature + " has changed to " + value);
            });
          thing.invokeAction("startMeasurement", { units: "Celsius" })
            .then(() => { console.log("Temperature measurement started."); })
            .catch(e => {
               console.log("Error starting measurement.");
               subscription.unsubscribe();
             })
        } catch(error) {
          console.log("Error during fetch or consume: " + error.message);
        };
      

The ExposedThing interface

The ExposedThing interface is the server API that allows defining request handlers, properties, Actions, and Events to a Thing. It also implements the ConsumedThing interface. An ExposedThing is created by the produce() method.

It is under consideration to use a constructor for ExposedThing instead of a factory method.

      ExposedThing implements ConsumedThing;
      interface ExposedThing {
        // define how to expose and run the Thing
        Promise<void> start();
        Promise<void> stop();
        Promise<void> register(optional USVString directory);
        Promise<void> unregister(optional USVString directory);
        Promise<void> emitEvent(DOMString eventName, any payload);
        // define Thing Description modifiers
        ExposedThing addProperty(ThingProperty property);
        ExposedThing removeProperty(DOMString name);
        ExposedThing addAction(ThingAction action);
        ExposedThing removeAction(DOMString name);
        ExposedThing addEvent(ThingEvent event);
        ExposedThing removeEvent(DOMString name);
        // define request handlers
        ExposedThing setPropertyReadHandler(DOMString name, PropertyReadHandler readHandler);
        ExposedThing setPropertyWriteHandler(DOMString name, PropertyWriteHandler writeHandler);
        ExposedThing setActionHandler(DOMString name, ActionHandler action);
      };
      callback PropertyReadHandler = Promise<any>();
      callback PropertyWriteHandler = Promise<void>(any value);
      callback ActionHandler = Promise<any>(any parameters);
    

The start() method

Start serving external requests for the Thing.

The stop() method

Stop serving external requests for the Thing.

The register() method

Generates the Thing Description given the properties, Actions and Event defined for this object. If a directory argument is given, make a request to register the Thing Description with the given WoT repository by invoking its register Action.

The unregister() method

If a directory argument is given, make a request to unregister the Thing Description with the given WoT repository by invoking its unregister Action. Then, and in the case no arguments were provided to this function, stop the Thing and remove the Thing Description.

The emitEvent() method

Emits an the event initialized with the event name specified by the eventName argument and data specified by the payload argument.

The DataSchema type

        typedef USVString DataSchema;
      

The DataSchema type represents a data type specified in the Thing Description in a serialized form.

DataSchema is under development, currently it can denote any type supported by the Thing Description and the WoT Runtime.

The addProperty() method

Adds a Property defined by the argument and updates the Thing Description. Throws on error. Returns a reference to the same object for supporting chaining.

The ThingProperty dictionary

          dictionary ThingProperty: SemanticAnnotations {
            required DOMString name;
            required DataSchema schema;
            any value;
            boolean writable = false;
            boolean observable = false;
          };
        

Represents the Thing Property description.

  • The name attribute represents the name of the Property.
  • The schema attribute represents the data type for the Property described by DataSchema.
  • The value attribute represents the value of the Property.
  • The writable attribute defines whether the Property can be updated. The default value is false.
  • The observable attribute defines whether the Property changes can be observed by an external client. The default value is false.

The removeProperty() method

Removes the Property specified by the name argument and updates the Thing Description. Throws on error. Returns a reference to the same object for supporting chaining.

The addAction() method

Adds an Action to the Thing object as defined by the action argument of type ThingAction and updates the Thing Description. Throws on error. Returns a reference to the same object for supporting chaining.

The ThingAction dictionary

          dictionary ThingAction: SemanticAnnotations {
            required DOMString name;
            DataSchema inputSchema;
            DataSchema outputSchema;
          };
      

The ThingAction dictionary describes the arguments and the return value.

  • The name attribute provides the Action name.
  • The inputSchema attribute provides the description of the input arguments (argument list is represented by an object). If missing, it means the action does not accept arguments.
  • The outputSchema attribute provides the description of the returned data. If missing, it means the action does not return data.

The removeAction() method

Removes the Action specified by the name argument and updates the Thing Description. Throws on error. Returns a reference to the same object for supporting chaining.

The addEvent() method

Adds an event to the Thing object as defined by the event argument of type ThingEvent and updates the Thing Description. Throws on error. Returns a reference to the same object for supporting chaining.

The ThingEvent dictionary

          dictionary ThingEvent: SemanticAnnotations {
            required DOMString name;
            DataSchema schema;
          };
        
  • The name attribute represents the event name.
  • The schema attribute represents the type of the data that is attached to the event. If missing, it means the event does not carry data.

The removeEvent() method

Removes the event specified by the name argument and updates the Thing Description. Returns a reference to the same object for supporting chaining.

The PropertyReadHandler callback

A function that returns a Promise and resolves it with the value of the Property matching the name argument to the setPropertyReadHandler function, or rejects with an error if the property is not found or the value cannot be retrieved.

The PropertyWriteHandler callback

A function called with value as argument that returns a Promise which is resolved when the value of the Property matching the name argument to the setPropertyReadHandler function is updated with value, or rejects with an error if the property is not found or the value cannot be updated.

Note that this function is invoked by implementations before the property is updated, so the code in this callback function can invoke the readProperty() method to find out the old value of the property, if needed. Therefore the old value is not provided to this method.

The ActionHandler callback

A function called with a parameters dictionary argument assembled by the WoT runtime based on the Thing Description and the external client request. It returns a Promise that rejects with an error or resolves if the action is successful or ongoing (may also resolve with a control object such as an Observable for actions that need progress notifications or that can be canceled).

The setPropertyReadHandler() method

Takes name as string argument and readHandler as argument of type PropertyReadHandler. Sets the handler function for reading the specified Property matched by name. Throws on error. Returns a reference to the same object for supporting chaining.

The readHandler callback function will implement reading a Property and SHOULD be called by implementations when a request for reading a Property is received from the underlying platform.

There SHOULD be at most one handler for any given Property and newly added handlers replace the old handlers. If no handler is initialized for any given Property, implementations SHOULD implement a default property read handler.

The setPropertyWriteHandler() method

Takes name as string argument and writeHandler as argument of type PropertyWriteHandler. Sets the handler function for writing the specified Property matched by name. Throws on error. Returns a reference to the same object for supporting chaining.

There SHOULD be at most one write handler for any given Property and newly added handlers replace the old handlers. If no write handler is initialized for any given Property, implementations SHOULD implement default property update and notifying observers on change.

The setActionHandler() method

Takes name as string argument and action as argument of type ActionHandler. Sets the handler function for the specified Action matched by name. Throws on error. Returns a reference to the same object for supporting chaining.

If provided, this callback function will implement invoking an Action and SHOULD be called by implementations when a request for invoking a Action is received from the underlying platform. The callback will receive a parameters dictionary argument.

There SHOULD be exactly one handler for any given Action. If no handler is initialized for any given Action, implementations SHOULD return error if the action is invoked by any client.

Examples

Below some ExposedThing interface examples are given.

        try {
          var thing = WoT.produce({ name: "tempSensor" });
          // manually add Interactions
          thing.addProperty({
            name: "temperature",
            value: 0.0,
            schema: '{ "type": "number" }'
            // use default values for the rest
          }).addProperty({
            name: "max",
            value: 0.0,
            schema: '{ "type": "number" }'
            // use default values for the rest
          }).addAction({
            name: "reset",
            // no input, no output
          }).addEvent({
            name: "onchange",
            schema: '{ "type": "number" }'
          });
          // add server functionality
          thing.setActionHandler("reset", () => {
            console.log("Resetting maximum");
            thing.writeProperty("max", 0.0);
          });
          thing.start().then(() => {
              thing.register();
          });
          // define Thing business logic
          setInterval( async () => {
            let mock = Math.random()*100;
            thing.writeProperty("temperature", mock);
            let old = await thing.readProperty("max");
            if (old < mock) {
              thing.writeProperty("max", mock);
              thing.emitEvent("onchange");
            }
          }, 1000);
        } catch (err) {
           console.log("Error creating ExposedThing: " + err);
        }
      
        let thingDescription = '{ "@context": [ "https://w3c.github.io/wot/w3c-wot-td-context.jsonld", "https://w3c.github.io/wot/w3c-wot-common-context.jsonld" ], "@type": [ "Thing", "Sensor" ], "name": "mySensor", "geo:location": "testspace", "interaction": [ { "@type": [ "Property", "Temperature" ], "name": "prop1", "schema": { "type": "number" }, "saref:TemperatureUnit": "degree_Celsius" } ] }';
        try {
          // note that produce() fails if thingDescription contains error
          let thing = WoT.produce(thingDescription);
          // Interactions were added from TD
          // WoT adds generic handler for reading any property
          // define a specific handler for one property
          let name = "examplePropertyName";
          thing.setPropertyReadHandler(name, () => {
            console.log("Handling read request for " + name);
            return new Promise((resolve, reject) => {
                let examplePropertyValue = 5;
                resolve(examplePropertyValue);
              },
              e => {
                console.log("Error");
              });
          });
          thing.start();
        } catch(err) {
           console.log("Error creating ExposedThing: " + err);
        }
      
        // fetch an external TD, e.g., to set up a proxy for that Thing
        WoT.fetch("http://myservice.org/mySensor/description").then(td => {
          // WoT.produce() ignores instance-specific metadata (security, form)
          let thing = WoT.produce(td);
          // Interactions were added from TD
          // add server functionality
          // ...
        });
      

Experimental extensions to the ConsumedThing interface

The ThingDescription related functionality, such as enumerating Properties, Actions, Events and links (introspection) is an API extension that is out of scope for this specification. However, the draft interfaces are defined here for informative purposes.

      partial interface ConsumedThing {
        sequence<ThingProperty> getProperties();
        sequence<ThingAction> getActions();
        sequence<ThingEvent> getEvents();
        sequence<TDLink> getLinks();
      };
    

The getProperties() method

Returns the list of Properties defined in the Thing Description of the Thing in the form of a list of ThingProperty objects.

The getActions() method

Returns the list of Actions defined in the Thing Description of the Thing in the form of a list of ThingAction objects.

The getEvents() method

Returns the list of Events defined in the Thing Description of the Thing in the form of a list of ThingEvent objects.

The getLinks() method

Returns the list of linked resources in Thing Description of the Thing in the form of a list of TDLink objects.

The TDLink dictionary

Contains a hyperlink reference, a relation type and a media type.

          dictionary TDLink {
              required USVString href;
              USVString mediaType;
              DOMString rel;
          };
        

The TDLink dictionary contains the following properties:

  • The href attribute represents a hyperlink reference.
  • The rel attribute represents a relation type.
  • The mediaType attribute represents a IANA media type. For TDs there will be registered media types, so applications will be able to check whether an `href` link points to a TD, i.e. whether the link is fetcheable with this API.

Observables

Observables are proposed to be included in ECMAScript and are used for handling pushed data associated with various possible sources, for instance events, timers, streams, etc. A minimal required implementation is described here.

This section is informal and contains rather laconic information for implementations on what to support for interoperability.

      interface Observable {
        Subscription subscribe((Observer or OnNext) next,
                               optional OnError error,
                               optional OnComplete complete);
      };
      interface Subscription {
        void unsubscribe();
        readonly attribute boolean closed;
      };
      interface Observer {
        void next(any value);
        void error(Error error);
        void complete();
      };
      callback OnNext = void (any value);
      callback OnError = void (Error error);
      callback OnComplete = void ();
    

The Observer interface

The Observer interface defines the callbacks needed to handle an Observable:

The Subscription interface

Contains the closed property of type boolean that tells if the subscription is closed or active.

Also, contains the unsubscribe() method that cancels the subscription, i.e. makes a request to the underlying platform to stop receiving data from the source, and sets the closed property to false.

The Observable interface

The Observable interface enabled subscribing to pushed data notifications by the subscribe() method:

Security and Privacy

Please see the WoT Security and Privacy repository for work in progress regarding threat models, assets, risks, recommended mitigations, and best practices for security and privacy for systems using the Web of Things. Once complete, security and privacy considerations relevant to the Scripting API will be summarized in this section.

Terminology and conventions

The generic WoT terminology is defined in [[!WOT-ARCHITECTURE]]: Thing, Thing Description (in short TD), Web of Things (in short WoT), WoT Interface, Protocol Bindings, WoT Runtime, Consuming a Thing Description, Thing Directory, WoT Interactions, Property, Action, Event etc.

JSON-LD is defined in [[!JSON-LD]] as a JSON document that is augmented with support for Linked Data by providing a @context property with a defining URI .

The terms URL and URL path are defined in [[!URL]].

The following terms are defined in [[!HTML5]] and are used in the context of browser implementations: browsing context, top-level browsing context, global object, incumbent settings object, Document, document base URL, Window, WindowProxy, origin, ASCII serialized origin, executing algorithms in parallel, queue a task, task source, iframe, valid MIME type.

A browsing context refers to the environment in which Document objects are presented to the user. A given browsing context has a single WindowProxy object, but it can have many Document objects, with their associated Window objects. The script execution context associated with the browsing context identifies the entity which invokes this API, which can be a web app, a web page, or an iframe.

The term secure context is defined in [[!WEBAPPSEC]].

Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError , script execution context, Promise, JSON, JSON.stringify and JSON.parse are defined in [[!ECMASCRIPT]].

DOMString, USVString, ArrayBuffer, BufferSource and any are defined in [[!WEBIDL]].

The algorithms utf-8 encode, and utf-8 decode are defined in [[!ENCODING]].

IANA media types (formerly known as MIME types) are defined in RFC2046.

The terms hyperlink reference and relation type are defined in [[!HTML5]] and RFC8288.

This document defines conformance criteria that apply to a single product: the UA (user agent) that implements the interfaces it contains.

This specification can be used for implementing the WoT Scripting API in multiple programming languages. The interface definitions are specified in [[!WEBIDL]].

The user agent (UA) may be implemented in the browser, or in a separate runtime environment, such as [Node.js](https://nodejs.org/en/) or small embedded runtimes.

Implementations that use ECMAScript executed in a browser to implement the APIs defined in this document MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]].

Implementations that use TypeScript or ECMAScript in a runtime to implement the APIs defined in this document MUST implement them in a manner consistent with the TypeScript Bindings defined in the TypeScript specification [[!TYPESCRIPT]].

This document serves a general description of the WoT Scripting API. Language and runtime specific issues are discussed in separate extensions of this document.

Changes

The following is a list of major changes to the document. For a complete list of changes, see the [github change log](https://github.com/w3c/wot-scripting-api/commits/master). You can also view the [recently closed bugs](https://github.com/w3c/wot-scripting-api/issues?page=1&state=closed).

Open issues

The following problems are being discussed and need most attention:

Acknowledgements

Special thanks to former editor Johannes Hund (until August 2017, when at Siemens AG) for developing this specification. Also, the editors would like to thank Dave Raggett, Matthias Kovatsch, Michael Koster and Michael McCool for their comments and guidance.