[Preposal] MDNS Service Discovery API

This is not intended to replace The [Proposal] Foreign Origin Space. It is meant to operate alongside it for Local Applications.

This is intended to extend the MDNS (Multicast DNS). Some Example MDNS-SD FQDN:

_service._proto.local.
_sip._tcp.local.
_googlecast._tcp.local.

Examples for this proposal however are:

_80._fileserver._https.local.
_my_first_chat_server._websocket.local.
_p2p_game._webrtc.local.
_walkie_talkie._webrtc.local.
_closed_captions._webtransport.local.

The format is _port._service._protocol.local with the port being optional

The following is a abstract TypeScript definition with details below.

enum Protocols {
    WebRTC,
    WebSocket,
    WebTransport,
    HTTP, //Optional / Future / Intial Request Allows CORS Override?
    HTTPS, //Optional / Future / Intial Request Allows CORS Override?
}

// See Preposal
type FQDN = string;

abstract class LocalServices {
    static readonly Protocols = Protocols;

    /**
     * Begins to advertise a service avalability.
     * @param MDNS_SD The FQDN of the service.
     * @param signal Allows for the advertisement to be cancled / stopped.
     */
    abstract advertise(MDNS_SD: FQDN, signal: AbortSignal): AsyncIterable<RTCPeerConnection|WebSocket|WebTransport>;

    /**
     * Watches for newly avalable services. (Passive)
     * @param MDNS_SD The FQDN of the service.
     * @param signal Allows for the watch to be cancled / stopped.
     */
    abstract watch(MDNS_SD: FQDN, signal?: AbortSignal): AsyncIterable<LocalServiceProvider>;

    /**
     * Sends a request for devices providing a service to respond. (Active)
     * @param MDNS_SD The FQDN of the service.
     */
    abstract find(MDNS_SD: FQDN): void;

    /**
     * Request approval to connect to service without connecting to service.
     * @param MDNS_SD The FQDN of the service.
     * @param name Name must fully include the protocol name in the FQDN, `_` may be converted into ` `, `-`, and punctuation(?) case insensitive.
     */
    abstract request(MDNS_SD: FQDN, name: string): Promise<boolean>;
}

abstract class LocalServiceProvider {
    /**
     * This allows for identifying the service provider in case of repeat appearances.
     */
    abstract uuid: Symbol;

    /**
     * The protocol of the Service Provider.
     */
    abstract protocol: Protocols;

    /**
     * Provides the upgrade / connection method for the ServiceProvider.
     */
    abstract get upgrade(): {WebRTC(): RTCPeerConnection} |
                            {WebSocket(): WebSocket} |
                            {WebTransport(): WebTransport}
}

This should allow for fully offline services for everything from games to file transfers in PWA’s. Default ports may need to be decided on for protocols or a basic negotiation protocol may need to be implemented for ports.

During first request / announcement the user will have to approve of the connection. It may also be a good idea to require the app be launched as a PWA first (similar to [Proposal] Foreign Origin Space), however this would limit local multiplayer in web-games that haven’t been installed for example.