@itwin/core-common
Version:
iTwin.js components common to frontend and backend
127 lines • 4.25 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module RpcInterface
*/
import { assert, BeEvent, BentleyStatus } from "@itwin/core-bentley";
import { IModelError } from "../../IModelError";
/** Defines a transport for push messages.
* @internal
*/
export class RpcPushTransport {
onMessage;
}
/** Defines a source of push messages.
* @internal
*/
export class RpcPushService {
/** The push service for the dedicated backend (for example, an electron or mobile app). */
static dedicated = new RpcPushService("dedicated");
name;
constructor(name) {
this.name = name;
}
}
/** Defines a named stream of push messages.
* @internal
*/
export class RpcPushChannel {
/** @internal */
static enabled = false;
static _channels = new Map();
static setup(transport) {
transport.onMessage = RpcPushChannel.notifySubscribers.bind(RpcPushChannel);
RpcPushChannel.enabled = true;
}
static notifySubscribers(channelId, messageData) {
const channel = this._channels.get(channelId);
if (!channel)
return;
for (const subscriber of channel._subscribers)
subscriber.onMessage.raiseEvent(messageData);
}
_subscribers = [];
name;
service;
get id() { return RpcPushChannel.formatId(this.name, this.service); }
get enabled() { return RpcPushChannel.enabled; }
subscribe() {
const subscription = new RpcPushSubscription(this);
this._subscribers.push(subscription);
return subscription;
}
static formatId(name, service) {
return `${service.name}-${name}`;
}
constructor(name, service) {
this.name = name;
this.service = service;
}
/** Creates a new RpcPushChannel.
* @throws IModelError if a channel with the specified name and service already exist.
*/
static create(name, service = RpcPushService.dedicated) {
return this.get(name, service, false);
}
/** Obtains an RpcPushChannel, creating it if one with the specified name and service does not already exists. */
static obtain(name, service = RpcPushService.dedicated) {
return this.get(name, service, true);
}
static get(name, service, reuseExisting) {
const id = this.formatId(name, service);
let channel = this._channels.get(id);
if (channel) {
if (!reuseExisting)
throw new IModelError(BentleyStatus.ERROR, `Channel "${id}" already exists.`);
++channel._refCount;
return channel;
}
channel = new RpcPushChannel(name, service);
this._channels.set(id, channel);
return channel;
}
_refCount = 1;
dispose() {
if (this.isDisposed)
return;
assert(this._refCount > 0);
if (--this._refCount === 0) {
RpcPushChannel._channels.delete(this.id);
this._subscribers.length = 0;
}
}
get isDisposed() {
return 0 === this._refCount;
}
}
/** Receives push messages from the backend.
* @internal
*/
export class RpcPushSubscription {
channel;
onMessage = new BeEvent();
/** @internal */
constructor(channel) {
this.channel = channel;
}
}
/** Sends push messages to the frontend.
* @internal
*/
export class RpcPushConnection {
static for(_channel, _client = undefined) {
throw new IModelError(BentleyStatus.ERROR, "Not implemented.");
}
channel;
client;
constructor(channel, client) {
this.channel = channel;
this.client = client;
}
}
//# sourceMappingURL=RpcPush.js.map