import { RPCChannel } from "./channel"; import { AnyConstructor } from "./internal"; import { MethodsOf, Proxied } from "./proxied"; import { RPCSession } from "./session"; /** * Creates an immediate proxy for a remote service without waiting for: * - The channel to be created * - The channel to be ready * - The RPC session to be created * - The RPC service to be acquired * * Automatically handles state loss by reacquiring the remote service once connection is ready again, and replaying * any active subscription calls. */ export declare function createServiceProxy(sessionPromise: Promise, klass: AnyConstructor, target?: U): Proxied & U; /** * Provides a powerful and ergonomic way to consume well-known remote objects (services) over Conduit. * * ### Why is this necessary? * * When using the lower level RPCSession API, a caller must: * - Choose and establish a communication channel (such as DurableSocket) for the communication to occur over * - Wait for the communication channel to become ready * - Request a remote service object via getRemoteService() and wait for the call to complete * * All of the above must occur before the first method call can be sent, and the caller must also maintain the * state of the connection themselves. When the communication channel loses state (for example, when a network * disconnect occurs), the caller must wait for the communication channel to become ready again, acquire a new * service object and otherwise manually restore the state of the connection. * * While the lower level API is extremely powerful and allows for communication patterns that are typically not * possible with other RPC systems, it is a lot of manual work to do a job that when using REST communication is * extremely simple. * * The Service class takes care of all of this for you and more. * * ### Constraints of using Conduit Services * * Effective use requires committing to several assumptions that Conduit itself does *not* make: * * - You will communicate over HTTP/Websockets using DurableSocket * (Conduit itself supports communicating over any arbitrary communication medium, including locally in the same * process). * * - You will primarily adopt a client/server architecture, where the party initiating the connection is the client * and the party receiving the connection is the server. * (Conduit does not require constraining the roles of participants) * * - You will primarily make method calls on well-known (service) objects, not transient objects * (Conduit supports leasing any object across the communication channel along with method calls to those * transient objects) * * - You will use method calls as the primary method of sending data to the server participant, and you will use * Observable events as your primary method of sending data to the client * (Conduit itself allows either party to acquire services from the other party and make method calls or event * subscriptions as they wish) * * ### Usage * * Servers providing Conduit Services should provide a library component (typically an NPM package) * which contains abstract service classes deriving from the Service base class. * - Each class should be decorated with `@Name()` to establish the well-known name for the service over Conduit. * - Each class should be decorated with `@URL()` to establish the default URL endpoint to connect to. * * Clients will acquire a local proxy for a service by calling the static `proxy()` method on the service's class. * Those objects can immediately be used to perform calls or subscribe to events. * * When the first call or event subscription occurs, the service proxy object will: * - Acquire or create an appropriate DurableSocketChannel for the configured endpoint URL. If one already exists, * it will be used (only one connection to the server will be established). * - Acquire or create an appropriate RPCSession for the configured endpoing URL. If one already exists, * it will be used (only one session will exist between client/server) * - Acquire a Conduit remote proxy for the service * * The service object will monitor the underlying channel for stateLost/ready events, and automatically reacquire remote * proxies on your behalf. The service object will also automatically maintain local state about event subscriptions and * ensure that the subscriptions are recreated when the connection becomes ready after state loss. * * Thus the intricacies of managing a long-lived RPC session while your app is running are abstracted away, letting you * simply make calls. Remember that Conduit will automatically reject any pending method calls that are outstanding * when connection loss occurs, allowing you to address that within your normal business logic layer. */ export declare class Service { /** * Construct a new proxy for this service pointing at the URL specified by the @URL() decorator. * The connection will be established and re-established automatically, the returned service * proxy is immediately available for use. Requests to the proxy will be automatically delayed * while the connection is established and the service object is obtained from the remote endpoint. * @param socketUrl The URL of the WebSocket server which supports Conduit. */ static proxy(this: AnyConstructor): MethodsOf; /** * Construct a new proxy for this service pointing at the given WebSocket URL. * The connection will be established and re-established automatically, the returned service * proxy is immediately available for use. Requests to the proxy will be automatically delayed * while the connection is established and the service object is obtained from the remote endpoint. * @param socketUrl The URL of the WebSocket server which supports Conduit. */ static proxy(this: AnyConstructor, socketUrl: string): Proxied; /** * Construct a new proxy for this service pointing at the given RPCChannel. * The returned service proxy is immediately available for use. Requests to the * proxy will be automatically delayed while the channel promise is resolved and the * service object is obtained from the remote endpoint. * @param channel A promise for obtaining the channel to use */ static proxy(this: AnyConstructor, channel: Promise): Proxied; /** * Construct a new proxy for the service identified by this class, which is running remotely on the * other side of the given RPCChannel. * * If channelOrEndpoint is a string, it is treated as a WebSockets URL, and a new durable WebSocket channel * connection will be created. If a connection to the endpoint already exists, the connection will be reused. * * The returned service proxy is immediately available for use without awaiting. Requests to the * proxy will be automatically delayed while the service object is obtained from the * remote endpoint. * * @param channel The channel to connect to */ static proxy(this: AnyConstructor, channel: RPCChannel): Proxied; static sessionOf(service: any): RPCSession; static channelOf(service: any): RPCChannel; static endpointOf(service: any): string; private static channelSessions; /** * Retrieve the RPCSession for a given Service object, as returned by Service.proxy() * @param service * @returns */ static sessionForProxy(service: Service): Promise; /** * Acquire the RPCSession object associated with the given channel. This will be the same session used * by Service.proxy() when used in concert with the given channel. * @param channel * @returns */ static sessionForChannel(channel: RPCChannel): RPCSession; private static endpointChannels; /** * Get or create the RPCChannel object associated with the given endpoint URL. This will be the same channel * used by Service.proxy() when used in concert with the given endpoint URL. * @param channel * @returns */ static channelForEndpoint(endpoint: string): RPCChannel; }