683 lines
27 KiB
JavaScript
683 lines
27 KiB
JavaScript
import { ContentType, Message, MessageFromClient, MessageToClient, CreateMailboxResponse, CreateMailboxRequest, RpcFrameType, SendReceipt, Ping, Pong, } from "./proto/wsmessages";
|
|
import { memoize, undef } from "../Utils";
|
|
const JsonContentTypeHandler = {
|
|
webSocketUrlPath: "/api/ws/send_receive_json",
|
|
sendMessageFromClient(mfc, ws) {
|
|
const obj = MessageFromClient.toJSON(mfc);
|
|
const jsonStr = JSON.stringify(obj);
|
|
ws.send(jsonStr);
|
|
}
|
|
};
|
|
const ProtobufContentTypeHandler = {
|
|
webSocketUrlPath: "/api/ws/send_receive_proto",
|
|
sendMessageFromClient(mfc, ws) {
|
|
const bytes = MessageFromClient.encode(mfc).finish();
|
|
ws.send(bytes);
|
|
}
|
|
};
|
|
export const ContentTypeHandler = {
|
|
Json: JsonContentTypeHandler,
|
|
Protobuf: ProtobufContentTypeHandler,
|
|
};
|
|
export function newHermesClient(rootUrl, contentTypeHandler) {
|
|
const hci = new HermesClientImpl(rootUrl, contentTypeHandler);
|
|
hci.mailbox().then((mbox) => {
|
|
const correlations = hci.correlations;
|
|
hci.channelMessageSubscribe({
|
|
id: "rpc-inbox",
|
|
state: "rpc-inbox",
|
|
readerKey: mbox.readerKey,
|
|
channel: "rpc-inbox",
|
|
startSeq: "all"
|
|
}, (me, msg) => {
|
|
var _a, _b, _c, _d, _e, _f;
|
|
if (me.messageBytes) {
|
|
try {
|
|
const msg = Message.decode(me.messageBytes);
|
|
const endPoint = (_b = (_a = msg.header) === null || _a === void 0 ? void 0 : _a.rpcHeader) === null || _b === void 0 ? void 0 : _b.endPoint;
|
|
if (((_d = (_c = msg.header) === null || _c === void 0 ? void 0 : _c.rpcHeader) === null || _d === void 0 ? void 0 : _d.frameType) === RpcFrameType.Request && endPoint == "ping") {
|
|
hci.sendPongResponse(mbox, msg, endPoint);
|
|
}
|
|
else {
|
|
const correlationId = (_f = (_e = msg.header) === null || _e === void 0 ? void 0 : _e.rpcHeader) === null || _f === void 0 ? void 0 : _f.correlationId;
|
|
if (correlationId) {
|
|
const resolve = correlations.get(correlationId);
|
|
if (resolve !== undefined) {
|
|
resolve(msg);
|
|
}
|
|
correlations.delete(correlationId);
|
|
}
|
|
}
|
|
}
|
|
catch (e) {
|
|
console.error("error decoding message", e);
|
|
}
|
|
}
|
|
// noop since we are only interested in the correlationId for rpc and that happens in onMessage
|
|
});
|
|
});
|
|
// send ping every 30 seconds
|
|
setInterval(() => hci.sendPing(), 30 * 1000);
|
|
return hci;
|
|
}
|
|
/**
|
|
* Create the mailbox
|
|
* @param channels
|
|
* @param rootUrl
|
|
* @returns
|
|
*/
|
|
async function createMailbox(channels, rootUrl) {
|
|
const mbox = {
|
|
channels: channels,
|
|
privateMetadata: {},
|
|
publicMetadata: {},
|
|
purgeTimeoutInMillis: 0,
|
|
closeTimeoutInMillis: 0,
|
|
extraData: {},
|
|
};
|
|
const mboxObj = CreateMailboxRequest.toJSON(mbox);
|
|
const mboxJson = JSON.stringify(mboxObj);
|
|
let mailboxResponse = undefined;
|
|
const response = await fetch(`${rootUrl}/api/create_mailbox`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: mboxJson,
|
|
});
|
|
if (response.ok) {
|
|
const responseJsonStr = await response.text();
|
|
mailboxResponse = CreateMailboxResponse.fromJSON(JSON.parse(responseJsonStr));
|
|
}
|
|
else {
|
|
throw new Error(`createMailbox failed with status ${response.status}`);
|
|
}
|
|
return mailboxResponse;
|
|
}
|
|
class Constants {
|
|
}
|
|
Constants.rpcInboxChannelName = "rpc-inbox";
|
|
Constants.rpcSentChannelName = "rpc-sent";
|
|
class HermesConnection {
|
|
constructor(clientImpl, mailbox, webSocket) {
|
|
this.clientImpl = clientImpl;
|
|
this.mailbox = mailbox;
|
|
this.webSocket = webSocket;
|
|
const self = this;
|
|
webSocket.onmessage = function (event) {
|
|
if (event.data instanceof ArrayBuffer) {
|
|
self.onWebSocketBinaryMessage(event.data);
|
|
}
|
|
else {
|
|
self.onWebSocketTextMessage(event.data);
|
|
}
|
|
};
|
|
webSocket.onclose = function (event) {
|
|
console.log("HermesConnection websocket closed", event);
|
|
clientImpl.reconnect();
|
|
};
|
|
// resend un ack'ed messages
|
|
clientImpl.sentMessagesWaitingForAck.forEach((smr, idempotentId) => {
|
|
self.sendSendMessageRequest(smr, false);
|
|
});
|
|
}
|
|
onWebSocketTextMessage(message) {
|
|
const jsonObj = JSON.parse(message);
|
|
const m2c = MessageToClient.fromJSON(jsonObj);
|
|
this.onMessageToClient(m2c);
|
|
}
|
|
onWebSocketBinaryMessage(message) {
|
|
const m2c = MessageToClient.decode(new Uint8Array(message));
|
|
this.onMessageToClient(m2c);
|
|
}
|
|
onMessageToClient(m2c) {
|
|
var _a, _b, _c;
|
|
if (m2c.notification !== undefined) {
|
|
console.log("hermes client received notification " + m2c.notification, m2c.notification);
|
|
}
|
|
else if (m2c.messageEnvelope !== undefined) {
|
|
const me = m2c.messageEnvelope;
|
|
if (me.messageBytes === undefined) {
|
|
console.log("hermes client received empty messageEnvelope", m2c.messageEnvelope);
|
|
}
|
|
else {
|
|
const subscriptionId = (_a = me.serverEnvelope) === null || _a === void 0 ? void 0 : _a.subscriptionId;
|
|
if (subscriptionId) {
|
|
const activeSub = this.clientImpl.activeSubscriptions.get(subscriptionId);
|
|
if (activeSub) {
|
|
const startSeq = (_b = me.serverEnvelope) === null || _b === void 0 ? void 0 : _b.sequence;
|
|
if (startSeq) {
|
|
activeSub.protoRawSubscription.startSeq = String(startSeq);
|
|
}
|
|
activeSub.onMessageEvent(me);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (m2c.sendMessageResponse !== undefined) {
|
|
const id = (_c = m2c.sendMessageResponse) === null || _c === void 0 ? void 0 : _c.idempotentId;
|
|
if (id) {
|
|
this.clientImpl.sentMessagesWaitingForAck.delete(id);
|
|
}
|
|
console.log("hermes client received SendMessageResponse", m2c.sendMessageResponse);
|
|
}
|
|
else if (m2c.subscribeResponse !== undefined) {
|
|
console.log("hermes client received subscribeResponse", m2c.subscribeResponse);
|
|
}
|
|
else if (m2c.ping !== undefined) {
|
|
this.webSocket.send(JSON.stringify({ pong: {} }));
|
|
}
|
|
else if (m2c.pong !== undefined) {
|
|
console.log("hermes client received pong");
|
|
}
|
|
}
|
|
sendMessageFromClient(mfc) {
|
|
console.log("sending websocket message", mfc);
|
|
this.clientImpl.contentTypeHandler.sendMessageFromClient(mfc, this.webSocket);
|
|
}
|
|
addActiveSubscription(activeSub) {
|
|
const listeners = this.clientImpl.activeSubscriptions.get(activeSub.subscriptionId);
|
|
if (listeners) {
|
|
throw Error(`subscriptionId ${activeSub.subscriptionId} is already subscribed`);
|
|
}
|
|
else {
|
|
this.clientImpl.activeSubscriptions.set(activeSub.subscriptionId, activeSub);
|
|
}
|
|
}
|
|
cdcSubscribe(cdcs, listener) {
|
|
const subscriptionId = "cdc-" + cdcs.tables.map((t) => t.database + "." + t.table).join("-");
|
|
const protoCdcs = {
|
|
id: subscriptionId,
|
|
matchers: cdcs.tables,
|
|
startSeq: cdcs.startSeq,
|
|
};
|
|
this.sendMessageFromClient({ subscribeRequest: { subscriptions: [{ changeDataCapture: protoCdcs }] } });
|
|
function onMessage(msg) {
|
|
const json = new TextDecoder().decode(msg.messageBytes);
|
|
const cdcEvent = JSON.parse(json);
|
|
listener(cdcEvent, cdcEvent.data);
|
|
}
|
|
this.addActiveSubscription({
|
|
subscriptionId: subscriptionId,
|
|
protoRawSubscription: protoCdcs,
|
|
onMessageEvent: onMessage,
|
|
protoSubscription: { changeDataCapture: protoCdcs }
|
|
});
|
|
}
|
|
channelMessageSubscribe(ms, listener) {
|
|
this.rawChannelSubscribe(ms, Message.decode, listener);
|
|
}
|
|
channelSendReceiptSubscribe(ms, listener) {
|
|
this.rawChannelSubscribe(ms, SendReceipt.decode, listener);
|
|
}
|
|
rawChannelSubscribe(ms, decoder, listener) {
|
|
const subscriptionId = ms.id;
|
|
if (!subscriptionId) {
|
|
throw new Error("MailboxSubscription id is undefined");
|
|
}
|
|
function onMessage(msg) {
|
|
if (msg.messageBytes === undefined) {
|
|
console.error("MessageEnvelope.messageBytes is undefined");
|
|
return;
|
|
}
|
|
const a = decoder(msg.messageBytes);
|
|
listener(msg, a);
|
|
}
|
|
this.sendMessageFromClient({ subscribeRequest: { subscriptions: [{ mailbox: ms }] } });
|
|
this.addActiveSubscription({
|
|
subscriptionId: subscriptionId,
|
|
onMessageEvent: onMessage,
|
|
protoRawSubscription: ms,
|
|
protoSubscription: { mailbox: ms }
|
|
});
|
|
}
|
|
sendPing() {
|
|
this.sendMessageFromClient({ ping: {} });
|
|
}
|
|
sendSendMessageRequest(smr, registerForAck) {
|
|
if (registerForAck && smr.idempotentId) {
|
|
this.clientImpl.sentMessagesWaitingForAck.set(smr.idempotentId, smr);
|
|
}
|
|
this.sendMessageFromClient({ sendMessageRequest: smr });
|
|
}
|
|
rawRpcCall(request) {
|
|
var _a;
|
|
const emptyBytes = new Uint8Array(0);
|
|
const correlationId = ((_a = this.mailbox.address) !== null && _a !== void 0 ? _a : "") + "-" + this.clientImpl.correlationIdCounter++;
|
|
const idempotentId = this.mailbox.address + correlationId;
|
|
const smr = {
|
|
channel: Constants.rpcInboxChannelName,
|
|
to: [request.to],
|
|
idempotentId: idempotentId,
|
|
message: {
|
|
header: {
|
|
rpcHeader: {
|
|
correlationId: correlationId,
|
|
endPoint: request.endPoint,
|
|
frameType: RpcFrameType.Request,
|
|
errorInfo: undefined,
|
|
},
|
|
sender: this.mailbox.address,
|
|
contentType: request.contentType,
|
|
extraHeaders: request.headers,
|
|
senderSequence: 0,
|
|
},
|
|
serverEnvelope: undefined,
|
|
senderEnvelope: {
|
|
created: Date.now(),
|
|
},
|
|
data: request.body !== undefined ? request.body : emptyBytes,
|
|
},
|
|
};
|
|
const promise = new Promise((resolve, reject) => {
|
|
this.clientImpl.correlations.set(correlationId, resolve);
|
|
});
|
|
this.sendSendMessageRequest(smr, true);
|
|
return promise;
|
|
}
|
|
rpcObserverSubscribe(readerKey, listener) {
|
|
console.log("rpcObserverSubscribe", readerKey);
|
|
const correlations = new Map();
|
|
const msInbox = {
|
|
id: "rpc-inbox-" + readerKey,
|
|
readerKey: readerKey,
|
|
channel: "rpc-inbox",
|
|
startSeq: "first",
|
|
};
|
|
this.channelMessageSubscribe(msInbox, (me, msg) => {
|
|
var _a, _b;
|
|
const correlationId = (_b = (_a = msg.header) === null || _a === void 0 ? void 0 : _a.rpcHeader) === null || _b === void 0 ? void 0 : _b.correlationId;
|
|
if (correlationId) {
|
|
var correlation = correlations.get(correlationId);
|
|
if (!correlation) {
|
|
correlation = new RpcRequestResponse(correlationId);
|
|
correlations.set(correlationId, correlation);
|
|
}
|
|
correlation.inboxEnvelope = me;
|
|
correlation.inboxMessage = msg;
|
|
listener(correlation);
|
|
}
|
|
});
|
|
const msSent = {
|
|
id: "rpc-sent-" + readerKey,
|
|
readerKey: readerKey,
|
|
channel: "rpc-sent",
|
|
startSeq: "first",
|
|
};
|
|
this.channelSendReceiptSubscribe(msSent, (me, sr) => {
|
|
var _a, _b, _c, _d, _e;
|
|
const msg = (_a = sr.request) === null || _a === void 0 ? void 0 : _a.message;
|
|
const correlationId = (_e = (_d = (_c = (_b = sr.request) === null || _b === void 0 ? void 0 : _b.message) === null || _c === void 0 ? void 0 : _c.header) === null || _d === void 0 ? void 0 : _d.rpcHeader) === null || _e === void 0 ? void 0 : _e.correlationId;
|
|
if (correlationId !== undefined) {
|
|
var correlation = correlations.get(correlationId);
|
|
if (correlation === undefined) {
|
|
correlation = new RpcRequestResponse(correlationId);
|
|
correlations.set(correlationId, correlation);
|
|
}
|
|
correlation.sentMessage = msg;
|
|
correlation.sendReceiptEnvelope = me;
|
|
correlation.sendReceipt = sr;
|
|
listener(correlation);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
class HermesClientImpl {
|
|
constructor(rootUrl, contentTypeHandler) {
|
|
this.correlationIdCounter = 0;
|
|
this.correlations = new Map();
|
|
this.activeSubscriptions = new Map();
|
|
this.sentMessagesWaitingForAck = new Map();
|
|
const thisHermesClientImpl = this;
|
|
this.rootUrl = rootUrl;
|
|
this.contentTypeHandler = contentTypeHandler;
|
|
this.mailboxResponseP = createMailbox([Constants.rpcInboxChannelName, Constants.rpcSentChannelName], rootUrl);
|
|
var tempMailboxResponseP = this.mailboxResponseP;
|
|
var tempWsUrl = new URL(rootUrl);
|
|
tempWsUrl.protocol = tempWsUrl.protocol.replace("http", "ws");
|
|
tempWsUrl.pathname = contentTypeHandler.webSocketUrlPath;
|
|
this.wsUrl = tempWsUrl.toString();
|
|
this.currentConn = this.newHermesConnection();
|
|
}
|
|
sendPongResponse(mbox, pingMsg, endPoint) {
|
|
var _a, _b, _c, _d, _e, _f;
|
|
const correlationId = (_b = (_a = pingMsg.header) === null || _a === void 0 ? void 0 : _a.rpcHeader) === null || _b === void 0 ? void 0 : _b.correlationId;
|
|
const sender = (_c = pingMsg === null || pingMsg === void 0 ? void 0 : pingMsg.header) === null || _c === void 0 ? void 0 : _c.sender;
|
|
const contentType = (_e = (_d = pingMsg === null || pingMsg === void 0 ? void 0 : pingMsg.header) === null || _d === void 0 ? void 0 : _d.contentType) !== null && _e !== void 0 ? _e : ContentType.UnspecifiedCT;
|
|
if (correlationId !== undefined && sender !== undefined) {
|
|
var ping = {};
|
|
if (pingMsg.data !== undefined) {
|
|
if (contentType == ContentType.Json) {
|
|
ping = Ping.fromJSON(pingMsg.data);
|
|
}
|
|
else {
|
|
ping = Ping.decode(pingMsg.data);
|
|
}
|
|
}
|
|
const pong = { payload: ping.payload };
|
|
var data;
|
|
if (contentType == ContentType.Json) {
|
|
data = new TextEncoder().encode(JSON.stringify(Pong.toJSON(pong)));
|
|
}
|
|
else {
|
|
data = Pong.encode(pong).finish();
|
|
}
|
|
const idempotentId = mbox.address + correlationId;
|
|
const smr = {
|
|
channel: Constants.rpcInboxChannelName,
|
|
to: [sender],
|
|
idempotentId: idempotentId,
|
|
message: {
|
|
header: {
|
|
rpcHeader: {
|
|
correlationId: correlationId,
|
|
endPoint: endPoint,
|
|
frameType: RpcFrameType.SuccessResponse,
|
|
errorInfo: undefined,
|
|
},
|
|
sender: mbox.address,
|
|
contentType: (_f = pingMsg === null || pingMsg === void 0 ? void 0 : pingMsg.header) === null || _f === void 0 ? void 0 : _f.contentType,
|
|
},
|
|
serverEnvelope: undefined,
|
|
senderEnvelope: {
|
|
created: Date.now(),
|
|
},
|
|
data: data,
|
|
},
|
|
};
|
|
this.withConn((conn) => {
|
|
conn.sendSendMessageRequest(smr, true);
|
|
});
|
|
}
|
|
else {
|
|
console.log("ignoring ping no correlation id", pingMsg);
|
|
}
|
|
}
|
|
reconnect() {
|
|
this.currentConn = this.newHermesConnection();
|
|
}
|
|
newHermesConnection() {
|
|
const outerThis = this;
|
|
return new Promise((resolve, reject) => {
|
|
this.mailboxResponseP.then((mbox) => {
|
|
var webSocket = new WebSocket(this.wsUrl);
|
|
webSocket.binaryType = "arraybuffer";
|
|
webSocket.onopen = function (event) {
|
|
console.log("hermes client websocket opened, sending first message");
|
|
const resubscriptions = Object.values(outerThis.activeSubscriptions).map((as) => { return as.protoSubscription; });
|
|
// send first message
|
|
const firstMessage = {
|
|
senderInfo: {
|
|
readerKey: mbox.readerKey,
|
|
address: mbox.address,
|
|
},
|
|
subscriptions: resubscriptions,
|
|
mailboxTimeoutInMs: 2 * 60 * 1000, // 2 minutes
|
|
};
|
|
const mfc = {
|
|
firstMessage: firstMessage,
|
|
};
|
|
console.log("sending first message");
|
|
outerThis.contentTypeHandler.sendMessageFromClient(mfc, webSocket);
|
|
console.log("resolving promise");
|
|
resolve(new HermesConnection(outerThis, mbox, webSocket));
|
|
};
|
|
});
|
|
});
|
|
}
|
|
mailbox() {
|
|
return this.mailboxResponseP;
|
|
}
|
|
async withConn(fn) {
|
|
return this.currentConn.then((conn) => fn(conn));
|
|
}
|
|
async withConnP(fn) {
|
|
return this.currentConn.then((conn) => fn(conn));
|
|
}
|
|
rawRpcCall(request) {
|
|
return this.withConnP((conn) => {
|
|
return conn.rawRpcCall(request);
|
|
});
|
|
}
|
|
cdcSubscribe(cdcs, listener) {
|
|
this.withConn((conn) => {
|
|
conn.cdcSubscribe(cdcs, listener);
|
|
});
|
|
}
|
|
rpcObserverSubscribe(readerKey, listener) {
|
|
console.log("outer rpcObserverSubscribe", readerKey);
|
|
this.withConn((conn) => {
|
|
console.log("inner rpcObserverSubscribe", readerKey);
|
|
conn.rpcObserverSubscribe(readerKey, listener);
|
|
});
|
|
}
|
|
channelMessageSubscribe(ms, listener) {
|
|
this.withConn((conn) => {
|
|
conn.channelMessageSubscribe(ms, listener);
|
|
});
|
|
}
|
|
channelSendReceiptSubscribe(ms, listener) {
|
|
this.withConn((conn) => {
|
|
conn.channelSendReceiptSubscribe(ms, listener);
|
|
});
|
|
}
|
|
sendPing() {
|
|
this.withConn((conn) => {
|
|
conn.sendPing();
|
|
});
|
|
}
|
|
}
|
|
export class RpcRequestResponse {
|
|
constructor(correlationId) {
|
|
this.correlationId = correlationId;
|
|
}
|
|
role() {
|
|
const ic = this.isClient();
|
|
if (ic) {
|
|
return "client";
|
|
}
|
|
else if (ic === false) {
|
|
return "server";
|
|
}
|
|
}
|
|
contentType() {
|
|
var _a, _b, _c, _d, _e, _f;
|
|
const contentType = (_f = (_c = (_b = (_a = this.requestMessage()) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.contentType) !== null && _c !== void 0 ? _c : (_e = (_d = this.responseMessage()) === null || _d === void 0 ? void 0 : _d.header) === null || _e === void 0 ? void 0 : _e.contentType) !== null && _f !== void 0 ? _f : ContentType.UnspecifiedCT;
|
|
return contentType;
|
|
}
|
|
isProtobuf() {
|
|
return this.contentType() === ContentType.Protobuf;
|
|
}
|
|
isJson() {
|
|
return this.contentType() === ContentType.Json;
|
|
}
|
|
isClient() {
|
|
var _a, _b, _c, _d, _e, _f;
|
|
const inboxFrameType = (_c = (_b = (_a = this.inboxMessage) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.rpcHeader) === null || _c === void 0 ? void 0 : _c.frameType;
|
|
const sentFrameType = (_f = (_e = (_d = this.sentMessage) === null || _d === void 0 ? void 0 : _d.header) === null || _e === void 0 ? void 0 : _e.rpcHeader) === null || _f === void 0 ? void 0 : _f.frameType;
|
|
if (sentFrameType === RpcFrameType.Request) {
|
|
return true;
|
|
}
|
|
else if (inboxFrameType === RpcFrameType.Request) {
|
|
return false;
|
|
}
|
|
}
|
|
hasRequestAndResponse() {
|
|
return this.sendReceiptEnvelope && this.inboxEnvelope ? true : false;
|
|
}
|
|
timeStarted() {
|
|
var _a, _b, _c, _d;
|
|
const ic = this.isClient();
|
|
var time = undef();
|
|
if (ic === true) {
|
|
time = (_b = (_a = this.sendReceiptEnvelope) === null || _a === void 0 ? void 0 : _a.serverEnvelope) === null || _b === void 0 ? void 0 : _b.created;
|
|
}
|
|
else if (ic === false) {
|
|
time = (_d = (_c = this.inboxEnvelope) === null || _c === void 0 ? void 0 : _c.serverEnvelope) === null || _d === void 0 ? void 0 : _d.created;
|
|
}
|
|
if (time) {
|
|
return new Date(time);
|
|
}
|
|
}
|
|
timeStartedL() {
|
|
var _a, _b, _c, _d;
|
|
const ic = this.isClient();
|
|
var time = undef();
|
|
if (ic === true) {
|
|
time = (_b = (_a = this.sendReceiptEnvelope) === null || _a === void 0 ? void 0 : _a.serverEnvelope) === null || _b === void 0 ? void 0 : _b.created;
|
|
}
|
|
else if (ic === false) {
|
|
time = (_d = (_c = this.inboxEnvelope) === null || _c === void 0 ? void 0 : _c.serverEnvelope) === null || _d === void 0 ? void 0 : _d.created;
|
|
}
|
|
return time;
|
|
}
|
|
timeCompleted() {
|
|
var _a, _b, _c, _d;
|
|
const ic = this.isClient();
|
|
var time = undefined;
|
|
if (ic === false) {
|
|
time = (_b = (_a = this.sendReceiptEnvelope) === null || _a === void 0 ? void 0 : _a.serverEnvelope) === null || _b === void 0 ? void 0 : _b.created;
|
|
}
|
|
else if (ic === true) {
|
|
time = (_d = (_c = this.inboxEnvelope) === null || _c === void 0 ? void 0 : _c.serverEnvelope) === null || _d === void 0 ? void 0 : _d.created;
|
|
}
|
|
if (time) {
|
|
return new Date(time);
|
|
}
|
|
}
|
|
durationInMillis() {
|
|
var _a, _b;
|
|
const ts = (_a = this.timeStarted()) === null || _a === void 0 ? void 0 : _a.getTime();
|
|
const tc = (_b = this.timeCompleted()) === null || _b === void 0 ? void 0 : _b.getTime();
|
|
if (ts && tc) {
|
|
return tc - ts;
|
|
}
|
|
}
|
|
endPoint() {
|
|
var _a, _b, _c;
|
|
return (_c = (_b = (_a = this.requestMessage()) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.rpcHeader) === null || _c === void 0 ? void 0 : _c.endPoint;
|
|
}
|
|
requestMessage() {
|
|
const ic = this.isClient();
|
|
if (ic === true) {
|
|
return this.sentMessage;
|
|
}
|
|
else if (ic === false) {
|
|
return this.inboxMessage;
|
|
}
|
|
}
|
|
requestEnvelope() {
|
|
const ic = this.isClient();
|
|
if (ic === true) {
|
|
return this.sendReceiptEnvelope;
|
|
}
|
|
else if (ic === false) {
|
|
return this.inboxEnvelope;
|
|
}
|
|
}
|
|
responseMessage() {
|
|
const ic = this.isClient();
|
|
if (ic === true) {
|
|
return this.inboxMessage;
|
|
}
|
|
else if (ic === false) {
|
|
return this.sentMessage;
|
|
}
|
|
}
|
|
responseEnvelope() {
|
|
const ic = this.isClient();
|
|
if (ic === true) {
|
|
return this.inboxEnvelope;
|
|
}
|
|
else if (ic === false) {
|
|
return this.sendReceiptEnvelope;
|
|
}
|
|
}
|
|
status() {
|
|
var _a, _b, _c;
|
|
const frameType = (_c = (_b = (_a = this.responseMessage()) === null || _a === void 0 ? void 0 : _a.header) === null || _b === void 0 ? void 0 : _b.rpcHeader) === null || _c === void 0 ? void 0 : _c.frameType;
|
|
if (!frameType) {
|
|
return "";
|
|
}
|
|
else if (frameType === RpcFrameType.ErrorResponse) {
|
|
return "error";
|
|
}
|
|
else if (frameType === RpcFrameType.SuccessResponse) {
|
|
return "success";
|
|
}
|
|
else {
|
|
return `Unexpected frame types ${frameType}`;
|
|
}
|
|
}
|
|
async processSchema(reqOrResp, data) {
|
|
if (this.isJson()) {
|
|
const jsonStr = new TextDecoder().decode(data);
|
|
return JSON.parse(jsonStr);
|
|
}
|
|
else {
|
|
const endPoint = this.endPoint();
|
|
if (endPoint === undefined) {
|
|
return {
|
|
"error": "no endpoint"
|
|
};
|
|
}
|
|
if (data === undefined) {
|
|
return {};
|
|
}
|
|
return protobufToJson(endPoint, reqOrResp, data);
|
|
}
|
|
}
|
|
async responseObj() {
|
|
var _a;
|
|
return this.processSchema("response", (_a = this.responseMessage()) === null || _a === void 0 ? void 0 : _a.data);
|
|
}
|
|
async requestObj() {
|
|
var _a;
|
|
return this.processSchema("request", (_a = this.requestMessage()) === null || _a === void 0 ? void 0 : _a.data);
|
|
}
|
|
}
|
|
const GlobalClient = {
|
|
get: memoize(() => newHermesClient("https://hermes-go.ahsrcm.com", JsonContentTypeHandler))
|
|
};
|
|
export default GlobalClient;
|
|
export function runHermesClientTest() {
|
|
}
|
|
export function runHermesClientTest2() {
|
|
// const hc = newHermesClient("https://hermes-go.ahsrcm.com", ContentType.Protobuf);
|
|
const hc = newHermesClient("https://hermes-go.ahsrcm.com", JsonContentTypeHandler);
|
|
hc.mailbox().then((mbox) => {
|
|
const cdcs = {
|
|
tables: [
|
|
{
|
|
database: "nefario",
|
|
table: "service",
|
|
},
|
|
],
|
|
startSeq: "new",
|
|
};
|
|
hc.cdcSubscribe(cdcs, (cdcEvent, a) => {
|
|
console.log("cdcEvent", cdcEvent);
|
|
});
|
|
});
|
|
// hc.correlatedRpcReader("rrb07167144dc644a0be22a85301afea7e" , (correlation) => {
|
|
// console.log("correlation", correlation);
|
|
// });
|
|
}
|
|
async function protobufToJson(schemaName, frametype, bytes) {
|
|
// const mboxObj = CreateMailboxRequest.toJSON(mbox);
|
|
// const mboxJson = JSON.stringify(mboxObj);
|
|
// let mailboxResponse: CreateMailboxResponse | undefined = undefined;
|
|
const rootUrl = GlobalClient.get().rootUrl;
|
|
const response = await fetch(`${rootUrl}/api/proto_to_json?schema=${schemaName}&frametype=${frametype}`, {
|
|
method: "POST",
|
|
body: bytes,
|
|
});
|
|
if (response.ok) {
|
|
const jsonStr = await response.text();
|
|
return JSON.parse(jsonStr);
|
|
}
|
|
else {
|
|
throw new Error(`proto_to_json failed with status ${response.status}`);
|
|
}
|
|
}
|