message-bridge-js
Advanced tools
Comparing version 0.9.3 to 0.9.4
@@ -1,2 +0,2 @@ | ||
var e,s,t=require("@microsoft/signalr"),r=require("uuid");function n(e,s=exports.MessageDirection.ToClient){return e.isError=e.type===exports.MessageType.Error,e.direction??=s,e}function o(e){return{name:e.name,payload:e.payload,type:e.type,direction:e.direction??exports.MessageDirection.ToClient,trackId:e.trackId??r.v4(),module:e.module,schema:e.schema,created:(new Date).toISOString(),isError:e.type===exports.MessageType.Error}}function i(e){return o({...e,type:exports.MessageType.Command})}function a(e){return o({...e,type:exports.MessageType.Query})}function c(e){return o({...e,type:exports.MessageType.Event})}exports.MessageType=void 0,(e=exports.MessageType||(exports.MessageType={})).Command="Command",e.CommandResponse="CommandResponse",e.Query="Query",e.QueryResponse="QueryResponse",e.Event="Event",e.Error="Error",exports.MessageDirection=void 0,(s=exports.MessageDirection||(exports.MessageDirection={})).ToClient="ToClient",s.ToServer="ToServer";class d{constructor(e){this.wsUri=void 0,this.connected=!1,this.trackedRequestMap={},this.subscribedEventListMap={},this.history=[],this.bridgeErrors=[],this.options={timeout:void 0,allowResponseValueWhenCancelled:!1,keepHistoryForReceivedMessages:!1,keepHistoryForSendingMessages:!1,logger:console?.log??(()=>{}),logParseIncomingMessageError:!0,timeoutFromBridgeOptionsMessage:e=>`Timeout after ${e}ms (BridgeOptions.timeout)`,timeoutFromRequestOptionsMessage:e=>`Timeout after ${e}ms (RequestOptions.timeout)`,logParseIncomingMessageErrorFormat:e=>["Bridge-Error (parse messageReceived):",e],logMessageReceived:!1,logMessageReceivedFormat:e=>["Bridge (messageReceived):",e],logSendingMessage:!1,logSendingMessageFormat:e=>["Bridge (sendingMessage):",e]},this.wsUri=e}setOptions(e){this.options={...this.options,...e}}getTrackedRequestMessage(e){return this.trackedRequestMap[e]?.requestMessage}cancelRequest(e){this.trackedRequestMap[e]&&(this.trackedRequestMap[e].requestMessage.cancelled=!0)}onConnect(){this.connected=!0,this.options.onConnect?.()}onError(e,s){void 0!==e&&this.bridgeErrors.push(e),this.options.onError?.(e,s)}onClose(e,s){void 0!==e&&this.bridgeErrors.push(e),this.connected=!1,this.options.onClose?.(e,s)}setOptionalRequestTimeout({requestMessage:e,timeout:s,onTimeout:t}){let r,n;if(void 0!==s?(r=this.options.timeoutFromRequestOptionsMessage?.(s)??`timeout after ${s}`,n=s):void 0!==this.options.timeout&&(r=this.options.timeoutFromBridgeOptionsMessage?.(this.options.timeout)??`timeout after ${this.options.timeout}`,n=this.options.timeout),void 0!==n)return setTimeout(()=>{e.timedOut=!0,t({reason:r,responseMessage:void 0,request:e.payload,requestMessage:e})},n)}sendMessageTracked(e){if(e.requestMessage.cancelled){let s=!0;if(void 0!==e.requestOptions.sendCancelled?s=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(s=!1),s)return Promise.resolve({request:e.requestMessage.payload,requestMessage:e.requestMessage,cancelled:!0})}return new Promise((s,t)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,t)=>{s(t)},handleError:(e,r)=>{this.options.throwOnTrackedError?t(r):s(r)}})}).finally(()=>{delete this.trackedRequestMap[e.requestMessage.trackId]})}sendMessage(e){const s=void 0;if(e.requestMessage.cancelled){let t=!0;if(void 0!==e.requestOptions.sendCancelled?t=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(t=!1),t)return Promise.resolve(s)}return new Promise((t,r)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,r)=>{t(e?s:r.response)},handleError:(e,n,o)=>{e&&t(s),this.options.avoidThrowOnNonTrackedError?t(o?.payload):r(n)}})})}sendMessagePromiseHandler({handleError:e,handleSuccess:s,requestMessage:t,requestOptions:r}){t.direction=exports.MessageDirection.ToServer,this.options.interceptSendMessage&&(t=this.options.interceptSendMessage(t));const n=(s,n)=>{o&&clearTimeout(o);const i={response:void 0,responseMessage:void 0,request:t.payload,requestMessage:t,isError:!0,error:n.reason,errorMessage:n.responseMessage,cancelled:t.cancelled||n.requestMessage?.cancelled||n.responseMessage?.cancelled,timedOut:t.timedOut||n.requestMessage?.timedOut||n.responseMessage?.timedOut};s&&this.options.callOnErrorWhenRequestIsCancelled&&r.callOnErrorWhenRequestIsCancelled||(this.onError(i),r.onError?.(i)),e(s,i,n)},o=this.setOptionalRequestTimeout({requestMessage:t,timeout:r.timeout,onTimeout:e=>{const s=this.handleCancelOptions(r,t);n(s,e)}});this.trackedRequestMap[t.trackId]={successTrack:e=>{const{response:n,cancelled:i}=this.handleCancelResponse(r,t,e),a={response:n,responseMessage:e,requestOptions:r,request:t.payload,requestMessage:t,isError:!1,cancelled:t.cancelled||e.cancelled,timedOut:t.timedOut||e.timedOut};o&&clearTimeout(o),(!i||this.options.callOnSuccessWhenRequestIsCancelled||r.callOnSuccessWhenRequestIsCancelled)&&(this.options.onSuccess?.(a),r.onSuccess?.(a)),s(i,a)},errorTrack:e=>{const{response:s,cancelled:o}=this.handleCancelResponse(r,t,e);n(o,{reason:s,responseMessage:e,request:t.payload,requestMessage:t})},requestMessage:t,requestOptions:r},this.internalSendMessage(t)}handleCancelOptions(e,s,t){let r=!1;void 0!==e.resolveCancelledForNonTracked?r=e.resolveCancelledForNonTracked:this.options.resolveCancelledNonTrackedRequest&&(r=!0);let n=!1;return(t?.cancelled||s.cancelled)&&(n=!0),r&&n&&(n=!1),n}handleCancelResponse(e,s,t){const r=this.handleCancelOptions(e,s,t);let n=t?.payload;return r&&(void 0!==e.allowResponseValueWhenCancelled?!0!==e.allowResponseValueWhenCancelled&&(n=void 0):!0!==this.options.allowResponseValueWhenCancelled&&(n=void 0)),{response:n,cancelled:r}}subscribeEvent({name:e,onEvent:s}){if(Array.isArray(e)){const t=e.map(e=>this.subscribeEvent({name:e,onEvent:s}));return()=>t.forEach(e=>e())}return this.subscribedEventListMap[e]||(this.subscribedEventListMap[e]=[]),this.subscribedEventListMap[e].push(s),()=>{const t=this.subscribedEventListMap[e].findIndex(e=>e===s);this.subscribedEventListMap[e].splice(t,1)}}createTrackedMessage(e){const s=e.requestMessage.trackId;let t={trackId:s,requestMessage:e.requestMessage,requestOptions:e.requestOptions,send:()=>this.sendMessage(e),sendTracked:()=>this.sendMessageTracked(e),cancel:()=>{e?.requestMessage&&(e.requestMessage.cancelled=!0),this.cancelRequest(s)}};return this.options.interceptCreatedMessageOptions&&(t=this.options.interceptCreatedMessageOptions(t)),t}createCommand(e){const s=i(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}createQuery(e){const s=a(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}sendCommand(e){return this.createCommand(e).send()}sendCommandTracked(e){return this.createCommand(e).sendTracked()}sendQuery(e){return this.createQuery(e).send()}sendQueryTracked(e){return this.createQuery(e).sendTracked()}createEvent(e){let s=c(e);s.direction=exports.MessageDirection.ToServer;let t={trackId:s.trackId,requestMessage:s,requestOptions:e,cancel:()=>{s&&(s.cancelled=!0)},send:()=>{if(s.cancelled)if(void 0!==e.sendCancelled){if(!e.sendCancelled)return}else if(!this.options.sendCancelledRequest)return;this.options.interceptSendMessage&&(s=this.options.interceptSendMessage(s)),this.internalSendMessage(s)}};return this.options.interceptCreatedEventMessageOptions&&(t=this.options.interceptCreatedEventMessageOptions(t)),t}sendEvent(e){return this.createEvent(e).send()}onMessage(e){let s;try{s="string"==typeof e?JSON.parse(e):e}catch(e){return void this.onError(e)}try{let e=n(s);this.options.interceptReceivedMessage&&(e=this.options.interceptReceivedMessage(e)),this.handleIncomingMessage(e)}catch(e){if(this.onError(e),this.options.logger&&this.options.logParseIncomingMessageError){const t=this.options.logParseIncomingMessageErrorFormat?.(s)??[e];this.options.logger(t)}}}internalSendMessage(e){if(this.options.keepHistoryForSendingMessages&&this.history.push(e),this.options.logger&&this.options.logSendingMessage){let s=!0;if(this.options.logSendingMessageFilter&&(s=!!e.name.match(this.options.logSendingMessageFilter)),s){const s=this.options.logSendingMessageFormat?.(e)??[e];this.options.logger(...s)}}this.options.onSend?.(e),this.sendNetworkMessage(e)}handleIncomingMessage(e){if(this.options.keepHistoryForReceivedMessages&&this.history.push(e),this.options.logger&&this.options.logMessageReceived){let s=!0;if(this.options.logMessageReceivedFilter&&(s=!!e.name.match(this.options.logMessageReceivedFilter)),s){const s=this.options.logMessageReceivedFormat?.(e)??[e];this.options.logger(...s)}}this.options.onMessage?.(e);let s=e.type!==exports.MessageType.Error;if(e.type===exports.MessageType.Event)return void this.receiveEventMessage(e);const t=this.trackedRequestMap[e.trackId];t&&(e.type===exports.MessageType.Error?(t.errorTrack(e),s=!0):t.successTrack(e),delete this.trackedRequestMap[e.trackId]),s||this.onError?.(e)}receiveEventMessage(e){this.subscribedEventListMap[e.name]&&this.subscribedEventListMap[e.name].forEach(s=>s(e.payload,e))}}exports.ClientSideMessageBridgeService=class extends d{constructor(...e){super(...e),this.server=void 0}setServer(e){this.server=e}connect(){if(!this.server)throw new Error("No server set");return this.server?.connect(e=>{const s=JSON.parse(JSON.stringify(e));this.onMessage(s),this.onConnect()}),Promise.resolve()}close(){this.onClose()}sendNetworkMessage(e){const s=JSON.parse(JSON.stringify(e));setTimeout(()=>{this.server?.onMessage(s)},10)}},exports.InMemoryClientSideServer=class{constructor(){this.store={},this.commands={},this.queries={},this.eventListeners={},this.sendMessage=void 0}saveToLocalStorage(e){localStorage.setItem(e,JSON.stringify(this.store))}loadFromLocalStorage(e){const s=localStorage.getItem(e);s&&(this.store=JSON.parse(s))}connect(e){this.sendMessage=e}sendError(e,s,t,r){const n=o({trackId:s,type:exports.MessageType.Error,name:"Error",payload:e,direction:exports.MessageDirection.ToClient,cancelled:t,timedOut:r});this.sendMessage?.(n)}createMessage(e){return o({...e,direction:exports.MessageDirection.ToClient})}sendResponse(e){const s=this.createMessage(e);this.sendMessage?.(s)}sendEvent(e,s){const t=o({type:exports.MessageType.Event,name:e,payload:s,direction:exports.MessageDirection.ToClient});this.sendMessage?.(t)}onMessage(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(s){return this.sendError({message:`Error parsing message: ${s}`,request:e,error:s,stack:s?.stack}),void console.error("Error parsing message",s)}if("Command"===e.type){if(!this.commands[e.name])return void this.sendError({message:`Command ${e.name} not found (Register it with addCommand)`,request:e},e.trackId);this.serverHandleCommand(e)}if("Query"===e.type){if(!this.queries[e.name])return void this.sendError({message:`Query ${e.name} not found (Register it with addQuery)`,request:e},e.trackId);this.serverHandleQuery(e)}if("Event"===e.type){if(!this.eventListeners[e.name])return void this.sendError({message:`Event ${e.name} not found (Register it with addEvent)`,request:e},e.trackId);this.serverHandleEvent(e)}}serverHandleCommand(e){const s=this.commands[e.name],t=e=>{this.sendMessage?.(e)},r=s=>this.createMessage({name:e.name,type:exports.MessageType.CommandResponse,payload:s,trackId:e.trackId}),n=e=>{const s=r(e);t(s)},o=(s,t,r)=>{this.sendError({message:s,request:e},e.trackId,t,r)},i=(e,s)=>{this.sendEvent(e,s)};try{s({requestMessage:e,request:e.payload,store:this.store,error:o,event:i,response:n,createResponseMessage:r,sendResponseMessage:t})}catch(s){o({message:`Error in command handler for '${e.name}'`,requestMessage:e,error:s,stack:s?.stack})}}serverHandleQuery(e){const s=e=>{this.sendMessage?.(e)},t=s=>this.createMessage({name:e.name,type:exports.MessageType.QueryResponse,payload:s,trackId:e.trackId});(0,this.queries[e.name])({requestMessage:e,request:e.payload,store:this.store,error:(s,t,r)=>{this.sendError({message:s,request:e},e.trackId,t,r)},event:(e,s)=>{this.sendEvent(e,s)},response:e=>{const r=t(e);s(r)},createResponseMessage:t,sendResponseMessage:s})}serverHandleEvent(e){(0,this.eventListeners[e.name])({requestMessage:e,request:e.payload,store:this.store,error:s=>{this.sendError({message:s,request:e},e.trackId)},event:(e,s)=>{this.sendEvent(e,s)}})}addCommand(e,s){this.commands[e]=s}addQuery(e,s){this.queries[e]=s}addEventListener(e,s){this.eventListeners[e]=s}},exports.MessageBridgeServiceBase=d,exports.SignalRMessageBridgeService=class extends d{constructor(...e){super(...e),this.connection=void 0}connect(e={}){if(this.connection=(new t.HubConnectionBuilder).withUrl(this.wsUri,e).withAutomaticReconnect().build(),!this.connection)throw new Error("Failed to create SignalR connection");return this.connection.on("ReceiveMessage",e=>{this.onMessage(e)}),this.connection.onclose(e=>{this.onClose(e)}),this.connection.start().then(()=>{this.onConnect()}).catch(e=>{this.onError(e)})}close(){this.connection?.stop(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.connection?.invoke("SendMessage",s).catch(e=>(this.onError(e),console.error(e.toString())))}},exports.WebsocketMessageBridgeService=class extends d{constructor(...e){super(...e),this.socket=void 0,this.connectedCallback=void 0}connect(){return this.socket=new WebSocket(this.wsUri),this.socket.addEventListener("message",e=>{this.onMessage(e.data)}),this.socket.addEventListener("close",e=>{this.onClose(e.reason,e)}),this.socket.addEventListener("error",e=>{this.onError(e,e)}),new Promise((e,s)=>{this.socket?.addEventListener("open",s=>{this.onConnect(),e()})})}close(){this.socket?.close(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.socket?.send(s)}},exports.createCommandMessage=i,exports.createEventMessage=c,exports.createMessage=o,exports.createMessageFromDto=n,exports.createQueryMessage=a; | ||
var e,s,t=require("@microsoft/signalr"),r=require("uuid");function o(e,s=exports.MessageDirection.ToClient){return e.isError=e.type===exports.MessageType.Error,e.direction??=s,e}function n(e){return{name:e.name,payload:e.payload,type:e.type,direction:e.direction??exports.MessageDirection.ToClient,trackId:e.trackId??r.v4(),module:e.module,schema:e.schema,created:(new Date).toISOString(),isError:e.type===exports.MessageType.Error}}function i(e){return n({...e,type:exports.MessageType.Command})}function a(e){return n({...e,type:exports.MessageType.Query})}function c(e){return n({...e,type:exports.MessageType.Event})}exports.MessageType=void 0,(e=exports.MessageType||(exports.MessageType={})).Command="Command",e.CommandResponse="CommandResponse",e.Query="Query",e.QueryResponse="QueryResponse",e.Event="Event",e.Error="Error",exports.MessageDirection=void 0,(s=exports.MessageDirection||(exports.MessageDirection={})).ToClient="ToClient",s.ToServer="ToServer";class d{constructor(e){this.wsUri=void 0,this.connected=!1,this.trackedRequestMap={},this.subscribedEventListMap={},this.history=[],this.bridgeErrors=[],this.options={timeout:void 0,allowResponseValueWhenCancelled:!1,keepHistoryForReceivedMessages:!1,keepHistoryForSendingMessages:!1,logger:console?.log??(()=>{}),logParseIncomingMessageError:!0,timeoutFromBridgeOptionsMessage:e=>`Timeout after ${e}ms (BridgeOptions.timeout)`,timeoutFromRequestOptionsMessage:e=>`Timeout after ${e}ms (RequestOptions.timeout)`,logParseIncomingMessageErrorFormat:e=>["Bridge-Error (parse messageReceived):",e],logMessageReceived:!1,logMessageReceivedFormat:e=>["Bridge (messageReceived):",e],logSendingMessage:!1,logSendingMessageFormat:e=>["Bridge (sendingMessage):",e]},this.wsUri=e}setOptions(e){this.options={...this.options,...e}}getTrackedRequestMessage(e){return this.trackedRequestMap[e]?.requestMessage}cancelRequest(e){this.trackedRequestMap[e]&&(this.trackedRequestMap[e].requestMessage.cancelled=!0)}onConnect(){this.connected=!0,this.options.onConnect?.()}onError(e,s){void 0!==e&&this.bridgeErrors.push(e),this.options.onError?.(e,s)}onClose(e,s){void 0!==e&&this.bridgeErrors.push(e),this.connected=!1,this.options.onClose?.(e,s)}setOptionalRequestTimeout({requestMessage:e,timeout:s,onTimeout:t}){let r,o;if(void 0!==s?(r=this.options.timeoutFromRequestOptionsMessage?.(s)??`timeout after ${s}`,o=s):void 0!==this.options.timeout&&(r=this.options.timeoutFromBridgeOptionsMessage?.(this.options.timeout)??`timeout after ${this.options.timeout}`,o=this.options.timeout),void 0!==o)return setTimeout(()=>{e.timedOut=!0,t({reason:r,responseMessage:void 0,request:e.payload,requestMessage:e})},o)}sendMessageTracked(e){if(e.requestMessage.cancelled){let s=!0;if(void 0!==e.requestOptions.sendCancelled?s=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(s=!1),s)return Promise.resolve({request:e.requestMessage.payload,requestMessage:e.requestMessage,cancelled:!0})}return new Promise((s,t)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,t)=>{s(t)},handleError:(e,r)=>{this.options.throwOnTrackedError?t(r):s(r)}})}).finally(()=>{delete this.trackedRequestMap[e.requestMessage.trackId]})}sendMessage(e){const s=void 0;if(e.requestMessage.cancelled){let t=!0;if(void 0!==e.requestOptions.sendCancelled?t=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(t=!1),t)return Promise.resolve(s)}return new Promise((t,r)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,r)=>{t(e?s:r.response)},handleError:(e,o,n)=>{e&&t(s),this.options.avoidThrowOnNonTrackedError?t(n?.payload):r(o)}})})}sendMessagePromiseHandler({handleError:e,handleSuccess:s,requestMessage:t,requestOptions:r}){t.direction=exports.MessageDirection.ToServer,this.options.interceptSendMessage&&(t=this.options.interceptSendMessage(t));const o=(s,o)=>{n&&clearTimeout(n);const i={response:void 0,responseMessage:void 0,request:t.payload,requestMessage:t,isError:!0,error:o.reason,errorMessage:o.responseMessage,cancelled:t.cancelled||o.requestMessage?.cancelled||o.responseMessage?.cancelled,timedOut:t.timedOut||o.requestMessage?.timedOut||o.responseMessage?.timedOut};s&&this.options.callOnErrorWhenRequestIsCancelled&&r.callOnErrorWhenRequestIsCancelled||(this.onError(i),r.onError?.(i)),e(s,i,o)},n=this.setOptionalRequestTimeout({requestMessage:t,timeout:r.timeout,onTimeout:e=>{const s=this.handleCancelOptions(r,t);o(s,e)}});this.trackedRequestMap[t.trackId]={successTrack:e=>{const{response:o,cancelled:i}=this.handleCancelResponse(r,t,e),a={response:o,responseMessage:e,requestOptions:r,request:t.payload,requestMessage:t,isError:!1,cancelled:t.cancelled||e.cancelled,timedOut:t.timedOut||e.timedOut};n&&clearTimeout(n),(!i||this.options.callOnSuccessWhenRequestIsCancelled||r.callOnSuccessWhenRequestIsCancelled)&&(this.options.onSuccess?.(a),r.onSuccess?.(a)),s(i,a)},errorTrack:e=>{const{response:s,cancelled:n}=this.handleCancelResponse(r,t,e);o(n,{reason:s,responseMessage:e,request:t.payload,requestMessage:t})},requestMessage:t,requestOptions:r},this.internalSendMessage(t)}handleCancelOptions(e,s,t){let r=!1;void 0!==e.resolveCancelledForNonTracked?r=e.resolveCancelledForNonTracked:this.options.resolveCancelledNonTrackedRequest&&(r=!0);let o=!1;return(t?.cancelled||s.cancelled)&&(o=!0),r&&o&&(o=!1),o}handleCancelResponse(e,s,t){const r=this.handleCancelOptions(e,s,t);let o=t?.payload;return r&&(void 0!==e.allowResponseValueWhenCancelled?!0!==e.allowResponseValueWhenCancelled&&(o=void 0):!0!==this.options.allowResponseValueWhenCancelled&&(o=void 0)),{response:o,cancelled:r}}subscribeEvent({name:e,onEvent:s}){if(Array.isArray(e)){const t=e.map(e=>this.subscribeEvent({name:e,onEvent:s}));return()=>t.forEach(e=>e())}return this.subscribedEventListMap[e]||(this.subscribedEventListMap[e]=[]),this.subscribedEventListMap[e].push(s),()=>{const t=this.subscribedEventListMap[e].findIndex(e=>e===s);this.subscribedEventListMap[e].splice(t,1)}}createTrackedMessage(e){const s=e.requestMessage.trackId;let t={trackId:s,requestMessage:e.requestMessage,requestOptions:e.requestOptions,send:()=>this.sendMessage(e),sendTracked:()=>this.sendMessageTracked(e),cancel:()=>{e?.requestMessage&&(e.requestMessage.cancelled=!0),this.cancelRequest(s)}};return this.options.interceptCreatedMessageOptions&&(t=this.options.interceptCreatedMessageOptions(t)),t}createCommand(e){const s=i(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}createQuery(e){const s=a(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}sendCommand(e){return this.createCommand(e).send()}sendCommandTracked(e){return this.createCommand(e).sendTracked()}sendQuery(e){return this.createQuery(e).send()}sendQueryTracked(e){return this.createQuery(e).sendTracked()}createEvent(e){let s=c(e);s.direction=exports.MessageDirection.ToServer;let t={trackId:s.trackId,requestMessage:s,requestOptions:e,cancel:()=>{s&&(s.cancelled=!0)},send:()=>{if(s.cancelled)if(void 0!==e.sendCancelled){if(!e.sendCancelled)return}else if(!this.options.sendCancelledRequest)return;this.options.interceptSendMessage&&(s=this.options.interceptSendMessage(s)),this.internalSendMessage(s)}};return this.options.interceptCreatedEventMessageOptions&&(t=this.options.interceptCreatedEventMessageOptions(t)),t}sendEvent(e){return this.createEvent(e).send()}onMessage(e){let s;try{s="string"==typeof e?JSON.parse(e):e}catch(e){return void this.onError(e)}try{let e=o(s);this.options.interceptReceivedMessage&&(e=this.options.interceptReceivedMessage(e)),this.handleIncomingMessage(e)}catch(e){if(this.onError(e),this.options.logger&&this.options.logParseIncomingMessageError){const t=this.options.logParseIncomingMessageErrorFormat?.(s)??[e];this.options.logger(t)}}}internalSendMessage(e){if(this.options.keepHistoryForSendingMessages&&this.history.push(e),this.options.logger&&this.options.logSendingMessage){let s=!0;if(this.options.logSendingMessageFilter&&(s=!!e.name.match(this.options.logSendingMessageFilter)),s){const s=this.options.logSendingMessageFormat?.(e)??[e];this.options.logger(...s)}}this.options.onSend?.(e),this.sendNetworkMessage(e)}handleIncomingMessage(e){if(this.options.keepHistoryForReceivedMessages&&this.history.push(e),this.options.logger&&this.options.logMessageReceived){let s=!0;if(this.options.logMessageReceivedFilter&&(s=!!e.name.match(this.options.logMessageReceivedFilter)),s){const s=this.options.logMessageReceivedFormat?.(e)??[e];this.options.logger(...s)}}this.options.onMessage?.(e);let s=e.type!==exports.MessageType.Error;if(e.type===exports.MessageType.Event)return void this.receiveEventMessage(e);const t=this.trackedRequestMap[e.trackId];t&&(e.type===exports.MessageType.Error?(t.errorTrack(e),s=!0):t.successTrack(e),delete this.trackedRequestMap[e.trackId]),s||this.onError?.(e)}receiveEventMessage(e){this.subscribedEventListMap[e.name]&&this.subscribedEventListMap[e.name].forEach(s=>s(e.payload,e))}}exports.ClientSideMessageBridgeService=class extends d{constructor(...e){super(...e),this.server=void 0}setServer(e){this.server=e}connect(){if(!this.server)throw new Error("No server set");return this.server?.connect(e=>{const s=JSON.parse(JSON.stringify(e));this.onMessage(s),this.onConnect()}),Promise.resolve()}close(){this.onClose()}sendNetworkMessage(e){const s=JSON.parse(JSON.stringify(e));setTimeout(()=>{this.server?.onMessage(s)},10)}},exports.InMemoryClientSideServer=class{constructor(){this.store={},this.commands={},this.queries={},this.eventListeners={},this.sendMessage=void 0}saveToLocalStorage(e){localStorage.setItem(e,JSON.stringify(this.store))}loadFromLocalStorage(e){const s=localStorage.getItem(e);s&&(this.store=JSON.parse(s))}connect(e){this.sendMessage=e}sendError(e,s,t,r){const o=n({trackId:s,type:exports.MessageType.Error,name:"Error",payload:e,direction:exports.MessageDirection.ToClient,cancelled:t,timedOut:r});this.sendMessage?.(o)}createMessage(e){return n({...e,direction:exports.MessageDirection.ToClient})}sendResponse(e){const s=this.createMessage(e);this.sendMessage?.(s)}sendEvent(e,s){const t=n({type:exports.MessageType.Event,name:e,payload:s,direction:exports.MessageDirection.ToClient});this.sendMessage?.(t)}onMessage(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(s){return this.sendError({message:`Error parsing message: ${s}`,request:e,error:s,stack:s?.stack}),void console.error("Error parsing message",s)}if("Command"===e.type){if(!this.commands[e.name])return void this.sendError({message:`Command ${e.name} not found (Register it with addCommand)`,request:e},e.trackId);this.serverHandleCommand(e)}if("Query"===e.type){if(!this.queries[e.name])return void this.sendError({message:`Query ${e.name} not found (Register it with addQuery)`,request:e},e.trackId);this.serverHandleQuery(e)}if("Event"===e.type){if(!this.eventListeners[e.name])return void this.sendError({message:`Event ${e.name} not found (Register it with addEvent)`,request:e},e.trackId);this.serverHandleEvent(e)}}serverHandleCommand(e){const s=this.commands[e.name],t=e=>{this.sendMessage?.(e)},r=s=>this.createMessage({name:e.name,type:exports.MessageType.CommandResponse,payload:s,trackId:e.trackId}),o=e=>{const s=r(e);t(s)},n=(s,t,r)=>{this.sendError({message:s,request:e},e.trackId,t,r)},i=(e,s)=>{this.sendEvent(e,s)};try{s({requestMessage:e,request:e.payload,store:this.store,error:n,event:i,response:o,createResponseMessage:r,sendResponseMessage:t})}catch(s){n({message:`Error in command handler for '${e.name}'`,requestMessage:e,error:s,stack:s?.stack})}}serverHandleQuery(e){const s=e=>{this.sendMessage?.(e)},t=s=>this.createMessage({name:e.name,type:exports.MessageType.QueryResponse,payload:s,trackId:e.trackId});(0,this.queries[e.name])({requestMessage:e,request:e.payload,store:this.store,error:(s,t,r)=>{this.sendError({message:s,request:e},e.trackId,t,r)},event:(e,s)=>{this.sendEvent(e,s)},response:e=>{const r=t(e);s(r)},createResponseMessage:t,sendResponseMessage:s})}serverHandleEvent(e){(0,this.eventListeners[e.name])({requestMessage:e,request:e.payload,store:this.store,error:s=>{this.sendError({message:s,request:e},e.trackId)},event:(e,s)=>{this.sendEvent(e,s)}})}addCommand(e,s){this.commands[e]=s}addQuery(e,s){this.queries[e]=s}addEventListener(e,s){this.eventListeners[e]=s}},exports.MapResponseType=function(e){switch(e){case exports.MessageType.Command:return exports.MessageType.CommandResponse;case exports.MessageType.Query:return exports.MessageType.QueryResponse;default:return e}},exports.MessageBridgeServiceBase=d,exports.SignalRMessageBridgeService=class extends d{constructor(...e){super(...e),this.connection=void 0}connect(e={}){if(this.connection=(new t.HubConnectionBuilder).withUrl(this.wsUri,e).withAutomaticReconnect().build(),!this.connection)throw new Error("Failed to create SignalR connection");return this.connection.on("ReceiveMessage",e=>{this.onMessage(e)}),this.connection.onclose(e=>{this.onClose(e)}),this.connection.start().then(()=>{this.onConnect()}).catch(e=>{this.onError(e)})}close(){this.connection?.stop(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.connection?.invoke("SendMessage",s).catch(e=>(this.onError(e),console.error(e.toString())))}},exports.WebsocketMessageBridgeService=class extends d{constructor(...e){super(...e),this.socket=void 0,this.connectedCallback=void 0}connect(){return this.socket=new WebSocket(this.wsUri),this.socket.addEventListener("message",e=>{this.onMessage(e.data)}),this.socket.addEventListener("close",e=>{this.onClose(e.reason,e)}),this.socket.addEventListener("error",e=>{this.onError(e,e)}),new Promise((e,s)=>{this.socket?.addEventListener("open",s=>{this.onConnect(),e()})})}close(){this.socket?.close(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.socket?.send(s)}},exports.createCommandMessage=i,exports.createEventMessage=c,exports.createMessage=n,exports.createMessageFromDto=o,exports.createQueryMessage=a; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
import{HubConnectionBuilder as e}from"@microsoft/signalr";import{v4 as s}from"uuid";var t,r;function n(e,s=r.ToClient){return e.isError=e.type===t.Error,e.direction??=s,e}function o(e){return{name:e.name,payload:e.payload,type:e.type,direction:e.direction??r.ToClient,trackId:e.trackId??s(),module:e.module,schema:e.schema,created:(new Date).toISOString(),isError:e.type===t.Error}}function i(e){return o({...e,type:t.Command})}function a(e){return o({...e,type:t.Query})}function c(e){return o({...e,type:t.Event})}!function(e){e.Command="Command",e.CommandResponse="CommandResponse",e.Query="Query",e.QueryResponse="QueryResponse",e.Event="Event",e.Error="Error"}(t||(t={})),function(e){e.ToClient="ToClient",e.ToServer="ToServer"}(r||(r={}));class d{constructor(e){this.wsUri=void 0,this.connected=!1,this.trackedRequestMap={},this.subscribedEventListMap={},this.history=[],this.bridgeErrors=[],this.options={timeout:void 0,allowResponseValueWhenCancelled:!1,keepHistoryForReceivedMessages:!1,keepHistoryForSendingMessages:!1,logger:console?.log??(()=>{}),logParseIncomingMessageError:!0,timeoutFromBridgeOptionsMessage:e=>`Timeout after ${e}ms (BridgeOptions.timeout)`,timeoutFromRequestOptionsMessage:e=>`Timeout after ${e}ms (RequestOptions.timeout)`,logParseIncomingMessageErrorFormat:e=>["Bridge-Error (parse messageReceived):",e],logMessageReceived:!1,logMessageReceivedFormat:e=>["Bridge (messageReceived):",e],logSendingMessage:!1,logSendingMessageFormat:e=>["Bridge (sendingMessage):",e]},this.wsUri=e}setOptions(e){this.options={...this.options,...e}}getTrackedRequestMessage(e){return this.trackedRequestMap[e]?.requestMessage}cancelRequest(e){this.trackedRequestMap[e]&&(this.trackedRequestMap[e].requestMessage.cancelled=!0)}onConnect(){this.connected=!0,this.options.onConnect?.()}onError(e,s){void 0!==e&&this.bridgeErrors.push(e),this.options.onError?.(e,s)}onClose(e,s){void 0!==e&&this.bridgeErrors.push(e),this.connected=!1,this.options.onClose?.(e,s)}setOptionalRequestTimeout({requestMessage:e,timeout:s,onTimeout:t}){let r,n;if(void 0!==s?(r=this.options.timeoutFromRequestOptionsMessage?.(s)??`timeout after ${s}`,n=s):void 0!==this.options.timeout&&(r=this.options.timeoutFromBridgeOptionsMessage?.(this.options.timeout)??`timeout after ${this.options.timeout}`,n=this.options.timeout),void 0!==n)return setTimeout(()=>{e.timedOut=!0,t({reason:r,responseMessage:void 0,request:e.payload,requestMessage:e})},n)}sendMessageTracked(e){if(e.requestMessage.cancelled){let s=!0;if(void 0!==e.requestOptions.sendCancelled?s=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(s=!1),s)return Promise.resolve({request:e.requestMessage.payload,requestMessage:e.requestMessage,cancelled:!0})}return new Promise((s,t)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,t)=>{s(t)},handleError:(e,r)=>{this.options.throwOnTrackedError?t(r):s(r)}})}).finally(()=>{delete this.trackedRequestMap[e.requestMessage.trackId]})}sendMessage(e){const s=void 0;if(e.requestMessage.cancelled){let t=!0;if(void 0!==e.requestOptions.sendCancelled?t=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(t=!1),t)return Promise.resolve(s)}return new Promise((t,r)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,r)=>{t(e?s:r.response)},handleError:(e,n,o)=>{e&&t(s),this.options.avoidThrowOnNonTrackedError?t(o?.payload):r(n)}})})}sendMessagePromiseHandler({handleError:e,handleSuccess:s,requestMessage:t,requestOptions:n}){t.direction=r.ToServer,this.options.interceptSendMessage&&(t=this.options.interceptSendMessage(t));const o=(s,r)=>{i&&clearTimeout(i);const o={response:void 0,responseMessage:void 0,request:t.payload,requestMessage:t,isError:!0,error:r.reason,errorMessage:r.responseMessage,cancelled:t.cancelled||r.requestMessage?.cancelled||r.responseMessage?.cancelled,timedOut:t.timedOut||r.requestMessage?.timedOut||r.responseMessage?.timedOut};s&&this.options.callOnErrorWhenRequestIsCancelled&&n.callOnErrorWhenRequestIsCancelled||(this.onError(o),n.onError?.(o)),e(s,o,r)},i=this.setOptionalRequestTimeout({requestMessage:t,timeout:n.timeout,onTimeout:e=>{const s=this.handleCancelOptions(n,t);o(s,e)}});this.trackedRequestMap[t.trackId]={successTrack:e=>{const{response:r,cancelled:o}=this.handleCancelResponse(n,t,e),a={response:r,responseMessage:e,requestOptions:n,request:t.payload,requestMessage:t,isError:!1,cancelled:t.cancelled||e.cancelled,timedOut:t.timedOut||e.timedOut};i&&clearTimeout(i),(!o||this.options.callOnSuccessWhenRequestIsCancelled||n.callOnSuccessWhenRequestIsCancelled)&&(this.options.onSuccess?.(a),n.onSuccess?.(a)),s(o,a)},errorTrack:e=>{const{response:s,cancelled:r}=this.handleCancelResponse(n,t,e);o(r,{reason:s,responseMessage:e,request:t.payload,requestMessage:t})},requestMessage:t,requestOptions:n},this.internalSendMessage(t)}handleCancelOptions(e,s,t){let r=!1;void 0!==e.resolveCancelledForNonTracked?r=e.resolveCancelledForNonTracked:this.options.resolveCancelledNonTrackedRequest&&(r=!0);let n=!1;return(t?.cancelled||s.cancelled)&&(n=!0),r&&n&&(n=!1),n}handleCancelResponse(e,s,t){const r=this.handleCancelOptions(e,s,t);let n=t?.payload;return r&&(void 0!==e.allowResponseValueWhenCancelled?!0!==e.allowResponseValueWhenCancelled&&(n=void 0):!0!==this.options.allowResponseValueWhenCancelled&&(n=void 0)),{response:n,cancelled:r}}subscribeEvent({name:e,onEvent:s}){if(Array.isArray(e)){const t=e.map(e=>this.subscribeEvent({name:e,onEvent:s}));return()=>t.forEach(e=>e())}return this.subscribedEventListMap[e]||(this.subscribedEventListMap[e]=[]),this.subscribedEventListMap[e].push(s),()=>{const t=this.subscribedEventListMap[e].findIndex(e=>e===s);this.subscribedEventListMap[e].splice(t,1)}}createTrackedMessage(e){const s=e.requestMessage.trackId;let t={trackId:s,requestMessage:e.requestMessage,requestOptions:e.requestOptions,send:()=>this.sendMessage(e),sendTracked:()=>this.sendMessageTracked(e),cancel:()=>{e?.requestMessage&&(e.requestMessage.cancelled=!0),this.cancelRequest(s)}};return this.options.interceptCreatedMessageOptions&&(t=this.options.interceptCreatedMessageOptions(t)),t}createCommand(e){const s=i(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}createQuery(e){const s=a(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}sendCommand(e){return this.createCommand(e).send()}sendCommandTracked(e){return this.createCommand(e).sendTracked()}sendQuery(e){return this.createQuery(e).send()}sendQueryTracked(e){return this.createQuery(e).sendTracked()}createEvent(e){let s=c(e);s.direction=r.ToServer;let t={trackId:s.trackId,requestMessage:s,requestOptions:e,cancel:()=>{s&&(s.cancelled=!0)},send:()=>{if(s.cancelled)if(void 0!==e.sendCancelled){if(!e.sendCancelled)return}else if(!this.options.sendCancelledRequest)return;this.options.interceptSendMessage&&(s=this.options.interceptSendMessage(s)),this.internalSendMessage(s)}};return this.options.interceptCreatedEventMessageOptions&&(t=this.options.interceptCreatedEventMessageOptions(t)),t}sendEvent(e){return this.createEvent(e).send()}onMessage(e){let s;try{s="string"==typeof e?JSON.parse(e):e}catch(e){return void this.onError(e)}try{let e=n(s);this.options.interceptReceivedMessage&&(e=this.options.interceptReceivedMessage(e)),this.handleIncomingMessage(e)}catch(e){if(this.onError(e),this.options.logger&&this.options.logParseIncomingMessageError){const t=this.options.logParseIncomingMessageErrorFormat?.(s)??[e];this.options.logger(t)}}}internalSendMessage(e){if(this.options.keepHistoryForSendingMessages&&this.history.push(e),this.options.logger&&this.options.logSendingMessage){let s=!0;if(this.options.logSendingMessageFilter&&(s=!!e.name.match(this.options.logSendingMessageFilter)),s){const s=this.options.logSendingMessageFormat?.(e)??[e];this.options.logger(...s)}}this.options.onSend?.(e),this.sendNetworkMessage(e)}handleIncomingMessage(e){if(this.options.keepHistoryForReceivedMessages&&this.history.push(e),this.options.logger&&this.options.logMessageReceived){let s=!0;if(this.options.logMessageReceivedFilter&&(s=!!e.name.match(this.options.logMessageReceivedFilter)),s){const s=this.options.logMessageReceivedFormat?.(e)??[e];this.options.logger(...s)}}this.options.onMessage?.(e);let s=e.type!==t.Error;if(e.type===t.Event)return void this.receiveEventMessage(e);const r=this.trackedRequestMap[e.trackId];r&&(e.type===t.Error?(r.errorTrack(e),s=!0):r.successTrack(e),delete this.trackedRequestMap[e.trackId]),s||this.onError?.(e)}receiveEventMessage(e){this.subscribedEventListMap[e.name]&&this.subscribedEventListMap[e.name].forEach(s=>s(e.payload,e))}}class l extends d{constructor(...e){super(...e),this.connection=void 0}connect(s={}){if(this.connection=(new e).withUrl(this.wsUri,s).withAutomaticReconnect().build(),!this.connection)throw new Error("Failed to create SignalR connection");return this.connection.on("ReceiveMessage",e=>{this.onMessage(e)}),this.connection.onclose(e=>{this.onClose(e)}),this.connection.start().then(()=>{this.onConnect()}).catch(e=>{this.onError(e)})}close(){this.connection?.stop(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.connection?.invoke("SendMessage",s).catch(e=>(this.onError(e),console.error(e.toString())))}}class h extends d{constructor(...e){super(...e),this.socket=void 0,this.connectedCallback=void 0}connect(){return this.socket=new WebSocket(this.wsUri),this.socket.addEventListener("message",e=>{this.onMessage(e.data)}),this.socket.addEventListener("close",e=>{this.onClose(e.reason,e)}),this.socket.addEventListener("error",e=>{this.onError(e,e)}),new Promise((e,s)=>{this.socket?.addEventListener("open",s=>{this.onConnect(),e()})})}close(){this.socket?.close(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.socket?.send(s)}}class u extends d{constructor(...e){super(...e),this.server=void 0}setServer(e){this.server=e}connect(){if(!this.server)throw new Error("No server set");return this.server?.connect(e=>{const s=JSON.parse(JSON.stringify(e));this.onMessage(s),this.onConnect()}),Promise.resolve()}close(){this.onClose()}sendNetworkMessage(e){const s=JSON.parse(JSON.stringify(e));setTimeout(()=>{this.server?.onMessage(s)},10)}}class g{constructor(){this.store={},this.commands={},this.queries={},this.eventListeners={},this.sendMessage=void 0}saveToLocalStorage(e){localStorage.setItem(e,JSON.stringify(this.store))}loadFromLocalStorage(e){const s=localStorage.getItem(e);s&&(this.store=JSON.parse(s))}connect(e){this.sendMessage=e}sendError(e,s,n,i){const a=o({trackId:s,type:t.Error,name:"Error",payload:e,direction:r.ToClient,cancelled:n,timedOut:i});this.sendMessage?.(a)}createMessage(e){return o({...e,direction:r.ToClient})}sendResponse(e){const s=this.createMessage(e);this.sendMessage?.(s)}sendEvent(e,s){const n=o({type:t.Event,name:e,payload:s,direction:r.ToClient});this.sendMessage?.(n)}onMessage(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(s){return this.sendError({message:`Error parsing message: ${s}`,request:e,error:s,stack:s?.stack}),void console.error("Error parsing message",s)}if("Command"===e.type){if(!this.commands[e.name])return void this.sendError({message:`Command ${e.name} not found (Register it with addCommand)`,request:e},e.trackId);this.serverHandleCommand(e)}if("Query"===e.type){if(!this.queries[e.name])return void this.sendError({message:`Query ${e.name} not found (Register it with addQuery)`,request:e},e.trackId);this.serverHandleQuery(e)}if("Event"===e.type){if(!this.eventListeners[e.name])return void this.sendError({message:`Event ${e.name} not found (Register it with addEvent)`,request:e},e.trackId);this.serverHandleEvent(e)}}serverHandleCommand(e){const s=this.commands[e.name],r=e=>{this.sendMessage?.(e)},n=s=>this.createMessage({name:e.name,type:t.CommandResponse,payload:s,trackId:e.trackId}),o=e=>{const s=n(e);r(s)},i=(s,t,r)=>{this.sendError({message:s,request:e},e.trackId,t,r)},a=(e,s)=>{this.sendEvent(e,s)};try{s({requestMessage:e,request:e.payload,store:this.store,error:i,event:a,response:o,createResponseMessage:n,sendResponseMessage:r})}catch(s){i({message:`Error in command handler for '${e.name}'`,requestMessage:e,error:s,stack:s?.stack})}}serverHandleQuery(e){const s=e=>{this.sendMessage?.(e)},r=s=>this.createMessage({name:e.name,type:t.QueryResponse,payload:s,trackId:e.trackId});(0,this.queries[e.name])({requestMessage:e,request:e.payload,store:this.store,error:(s,t,r)=>{this.sendError({message:s,request:e},e.trackId,t,r)},event:(e,s)=>{this.sendEvent(e,s)},response:e=>{const t=r(e);s(t)},createResponseMessage:r,sendResponseMessage:s})}serverHandleEvent(e){(0,this.eventListeners[e.name])({requestMessage:e,request:e.payload,store:this.store,error:s=>{this.sendError({message:s,request:e},e.trackId)},event:(e,s)=>{this.sendEvent(e,s)}})}addCommand(e,s){this.commands[e]=s}addQuery(e,s){this.queries[e]=s}addEventListener(e,s){this.eventListeners[e]=s}}export{u as ClientSideMessageBridgeService,g as InMemoryClientSideServer,d as MessageBridgeServiceBase,r as MessageDirection,t as MessageType,l as SignalRMessageBridgeService,h as WebsocketMessageBridgeService,i as createCommandMessage,c as createEventMessage,o as createMessage,n as createMessageFromDto,a as createQueryMessage}; | ||
import{HubConnectionBuilder as e}from"@microsoft/signalr";import{v4 as s}from"uuid";var t,r;function n(e,s=r.ToClient){return e.isError=e.type===t.Error,e.direction??=s,e}function o(e){switch(e){case t.Command:return t.CommandResponse;case t.Query:return t.QueryResponse;default:return e}}function i(e){return{name:e.name,payload:e.payload,type:e.type,direction:e.direction??r.ToClient,trackId:e.trackId??s(),module:e.module,schema:e.schema,created:(new Date).toISOString(),isError:e.type===t.Error}}function a(e){return i({...e,type:t.Command})}function c(e){return i({...e,type:t.Query})}function d(e){return i({...e,type:t.Event})}!function(e){e.Command="Command",e.CommandResponse="CommandResponse",e.Query="Query",e.QueryResponse="QueryResponse",e.Event="Event",e.Error="Error"}(t||(t={})),function(e){e.ToClient="ToClient",e.ToServer="ToServer"}(r||(r={}));class l{constructor(e){this.wsUri=void 0,this.connected=!1,this.trackedRequestMap={},this.subscribedEventListMap={},this.history=[],this.bridgeErrors=[],this.options={timeout:void 0,allowResponseValueWhenCancelled:!1,keepHistoryForReceivedMessages:!1,keepHistoryForSendingMessages:!1,logger:console?.log??(()=>{}),logParseIncomingMessageError:!0,timeoutFromBridgeOptionsMessage:e=>`Timeout after ${e}ms (BridgeOptions.timeout)`,timeoutFromRequestOptionsMessage:e=>`Timeout after ${e}ms (RequestOptions.timeout)`,logParseIncomingMessageErrorFormat:e=>["Bridge-Error (parse messageReceived):",e],logMessageReceived:!1,logMessageReceivedFormat:e=>["Bridge (messageReceived):",e],logSendingMessage:!1,logSendingMessageFormat:e=>["Bridge (sendingMessage):",e]},this.wsUri=e}setOptions(e){this.options={...this.options,...e}}getTrackedRequestMessage(e){return this.trackedRequestMap[e]?.requestMessage}cancelRequest(e){this.trackedRequestMap[e]&&(this.trackedRequestMap[e].requestMessage.cancelled=!0)}onConnect(){this.connected=!0,this.options.onConnect?.()}onError(e,s){void 0!==e&&this.bridgeErrors.push(e),this.options.onError?.(e,s)}onClose(e,s){void 0!==e&&this.bridgeErrors.push(e),this.connected=!1,this.options.onClose?.(e,s)}setOptionalRequestTimeout({requestMessage:e,timeout:s,onTimeout:t}){let r,n;if(void 0!==s?(r=this.options.timeoutFromRequestOptionsMessage?.(s)??`timeout after ${s}`,n=s):void 0!==this.options.timeout&&(r=this.options.timeoutFromBridgeOptionsMessage?.(this.options.timeout)??`timeout after ${this.options.timeout}`,n=this.options.timeout),void 0!==n)return setTimeout(()=>{e.timedOut=!0,t({reason:r,responseMessage:void 0,request:e.payload,requestMessage:e})},n)}sendMessageTracked(e){if(e.requestMessage.cancelled){let s=!0;if(void 0!==e.requestOptions.sendCancelled?s=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(s=!1),s)return Promise.resolve({request:e.requestMessage.payload,requestMessage:e.requestMessage,cancelled:!0})}return new Promise((s,t)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,t)=>{s(t)},handleError:(e,r)=>{this.options.throwOnTrackedError?t(r):s(r)}})}).finally(()=>{delete this.trackedRequestMap[e.requestMessage.trackId]})}sendMessage(e){const s=void 0;if(e.requestMessage.cancelled){let t=!0;if(void 0!==e.requestOptions.sendCancelled?t=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(t=!1),t)return Promise.resolve(s)}return new Promise((t,r)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,r)=>{t(e?s:r.response)},handleError:(e,n,o)=>{e&&t(s),this.options.avoidThrowOnNonTrackedError?t(o?.payload):r(n)}})})}sendMessagePromiseHandler({handleError:e,handleSuccess:s,requestMessage:t,requestOptions:n}){t.direction=r.ToServer,this.options.interceptSendMessage&&(t=this.options.interceptSendMessage(t));const o=(s,r)=>{i&&clearTimeout(i);const o={response:void 0,responseMessage:void 0,request:t.payload,requestMessage:t,isError:!0,error:r.reason,errorMessage:r.responseMessage,cancelled:t.cancelled||r.requestMessage?.cancelled||r.responseMessage?.cancelled,timedOut:t.timedOut||r.requestMessage?.timedOut||r.responseMessage?.timedOut};s&&this.options.callOnErrorWhenRequestIsCancelled&&n.callOnErrorWhenRequestIsCancelled||(this.onError(o),n.onError?.(o)),e(s,o,r)},i=this.setOptionalRequestTimeout({requestMessage:t,timeout:n.timeout,onTimeout:e=>{const s=this.handleCancelOptions(n,t);o(s,e)}});this.trackedRequestMap[t.trackId]={successTrack:e=>{const{response:r,cancelled:o}=this.handleCancelResponse(n,t,e),a={response:r,responseMessage:e,requestOptions:n,request:t.payload,requestMessage:t,isError:!1,cancelled:t.cancelled||e.cancelled,timedOut:t.timedOut||e.timedOut};i&&clearTimeout(i),(!o||this.options.callOnSuccessWhenRequestIsCancelled||n.callOnSuccessWhenRequestIsCancelled)&&(this.options.onSuccess?.(a),n.onSuccess?.(a)),s(o,a)},errorTrack:e=>{const{response:s,cancelled:r}=this.handleCancelResponse(n,t,e);o(r,{reason:s,responseMessage:e,request:t.payload,requestMessage:t})},requestMessage:t,requestOptions:n},this.internalSendMessage(t)}handleCancelOptions(e,s,t){let r=!1;void 0!==e.resolveCancelledForNonTracked?r=e.resolveCancelledForNonTracked:this.options.resolveCancelledNonTrackedRequest&&(r=!0);let n=!1;return(t?.cancelled||s.cancelled)&&(n=!0),r&&n&&(n=!1),n}handleCancelResponse(e,s,t){const r=this.handleCancelOptions(e,s,t);let n=t?.payload;return r&&(void 0!==e.allowResponseValueWhenCancelled?!0!==e.allowResponseValueWhenCancelled&&(n=void 0):!0!==this.options.allowResponseValueWhenCancelled&&(n=void 0)),{response:n,cancelled:r}}subscribeEvent({name:e,onEvent:s}){if(Array.isArray(e)){const t=e.map(e=>this.subscribeEvent({name:e,onEvent:s}));return()=>t.forEach(e=>e())}return this.subscribedEventListMap[e]||(this.subscribedEventListMap[e]=[]),this.subscribedEventListMap[e].push(s),()=>{const t=this.subscribedEventListMap[e].findIndex(e=>e===s);this.subscribedEventListMap[e].splice(t,1)}}createTrackedMessage(e){const s=e.requestMessage.trackId;let t={trackId:s,requestMessage:e.requestMessage,requestOptions:e.requestOptions,send:()=>this.sendMessage(e),sendTracked:()=>this.sendMessageTracked(e),cancel:()=>{e?.requestMessage&&(e.requestMessage.cancelled=!0),this.cancelRequest(s)}};return this.options.interceptCreatedMessageOptions&&(t=this.options.interceptCreatedMessageOptions(t)),t}createCommand(e){const s=a(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}createQuery(e){const s=c(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}sendCommand(e){return this.createCommand(e).send()}sendCommandTracked(e){return this.createCommand(e).sendTracked()}sendQuery(e){return this.createQuery(e).send()}sendQueryTracked(e){return this.createQuery(e).sendTracked()}createEvent(e){let s=d(e);s.direction=r.ToServer;let t={trackId:s.trackId,requestMessage:s,requestOptions:e,cancel:()=>{s&&(s.cancelled=!0)},send:()=>{if(s.cancelled)if(void 0!==e.sendCancelled){if(!e.sendCancelled)return}else if(!this.options.sendCancelledRequest)return;this.options.interceptSendMessage&&(s=this.options.interceptSendMessage(s)),this.internalSendMessage(s)}};return this.options.interceptCreatedEventMessageOptions&&(t=this.options.interceptCreatedEventMessageOptions(t)),t}sendEvent(e){return this.createEvent(e).send()}onMessage(e){let s;try{s="string"==typeof e?JSON.parse(e):e}catch(e){return void this.onError(e)}try{let e=n(s);this.options.interceptReceivedMessage&&(e=this.options.interceptReceivedMessage(e)),this.handleIncomingMessage(e)}catch(e){if(this.onError(e),this.options.logger&&this.options.logParseIncomingMessageError){const t=this.options.logParseIncomingMessageErrorFormat?.(s)??[e];this.options.logger(t)}}}internalSendMessage(e){if(this.options.keepHistoryForSendingMessages&&this.history.push(e),this.options.logger&&this.options.logSendingMessage){let s=!0;if(this.options.logSendingMessageFilter&&(s=!!e.name.match(this.options.logSendingMessageFilter)),s){const s=this.options.logSendingMessageFormat?.(e)??[e];this.options.logger(...s)}}this.options.onSend?.(e),this.sendNetworkMessage(e)}handleIncomingMessage(e){if(this.options.keepHistoryForReceivedMessages&&this.history.push(e),this.options.logger&&this.options.logMessageReceived){let s=!0;if(this.options.logMessageReceivedFilter&&(s=!!e.name.match(this.options.logMessageReceivedFilter)),s){const s=this.options.logMessageReceivedFormat?.(e)??[e];this.options.logger(...s)}}this.options.onMessage?.(e);let s=e.type!==t.Error;if(e.type===t.Event)return void this.receiveEventMessage(e);const r=this.trackedRequestMap[e.trackId];r&&(e.type===t.Error?(r.errorTrack(e),s=!0):r.successTrack(e),delete this.trackedRequestMap[e.trackId]),s||this.onError?.(e)}receiveEventMessage(e){this.subscribedEventListMap[e.name]&&this.subscribedEventListMap[e.name].forEach(s=>s(e.payload,e))}}class h extends l{constructor(...e){super(...e),this.connection=void 0}connect(s={}){if(this.connection=(new e).withUrl(this.wsUri,s).withAutomaticReconnect().build(),!this.connection)throw new Error("Failed to create SignalR connection");return this.connection.on("ReceiveMessage",e=>{this.onMessage(e)}),this.connection.onclose(e=>{this.onClose(e)}),this.connection.start().then(()=>{this.onConnect()}).catch(e=>{this.onError(e)})}close(){this.connection?.stop(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.connection?.invoke("SendMessage",s).catch(e=>(this.onError(e),console.error(e.toString())))}}class u extends l{constructor(...e){super(...e),this.socket=void 0,this.connectedCallback=void 0}connect(){return this.socket=new WebSocket(this.wsUri),this.socket.addEventListener("message",e=>{this.onMessage(e.data)}),this.socket.addEventListener("close",e=>{this.onClose(e.reason,e)}),this.socket.addEventListener("error",e=>{this.onError(e,e)}),new Promise((e,s)=>{this.socket?.addEventListener("open",s=>{this.onConnect(),e()})})}close(){this.socket?.close(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.socket?.send(s)}}class g extends l{constructor(...e){super(...e),this.server=void 0}setServer(e){this.server=e}connect(){if(!this.server)throw new Error("No server set");return this.server?.connect(e=>{const s=JSON.parse(JSON.stringify(e));this.onMessage(s),this.onConnect()}),Promise.resolve()}close(){this.onClose()}sendNetworkMessage(e){const s=JSON.parse(JSON.stringify(e));setTimeout(()=>{this.server?.onMessage(s)},10)}}class p{constructor(){this.store={},this.commands={},this.queries={},this.eventListeners={},this.sendMessage=void 0}saveToLocalStorage(e){localStorage.setItem(e,JSON.stringify(this.store))}loadFromLocalStorage(e){const s=localStorage.getItem(e);s&&(this.store=JSON.parse(s))}connect(e){this.sendMessage=e}sendError(e,s,n,o){const a=i({trackId:s,type:t.Error,name:"Error",payload:e,direction:r.ToClient,cancelled:n,timedOut:o});this.sendMessage?.(a)}createMessage(e){return i({...e,direction:r.ToClient})}sendResponse(e){const s=this.createMessage(e);this.sendMessage?.(s)}sendEvent(e,s){const n=i({type:t.Event,name:e,payload:s,direction:r.ToClient});this.sendMessage?.(n)}onMessage(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(s){return this.sendError({message:`Error parsing message: ${s}`,request:e,error:s,stack:s?.stack}),void console.error("Error parsing message",s)}if("Command"===e.type){if(!this.commands[e.name])return void this.sendError({message:`Command ${e.name} not found (Register it with addCommand)`,request:e},e.trackId);this.serverHandleCommand(e)}if("Query"===e.type){if(!this.queries[e.name])return void this.sendError({message:`Query ${e.name} not found (Register it with addQuery)`,request:e},e.trackId);this.serverHandleQuery(e)}if("Event"===e.type){if(!this.eventListeners[e.name])return void this.sendError({message:`Event ${e.name} not found (Register it with addEvent)`,request:e},e.trackId);this.serverHandleEvent(e)}}serverHandleCommand(e){const s=this.commands[e.name],r=e=>{this.sendMessage?.(e)},n=s=>this.createMessage({name:e.name,type:t.CommandResponse,payload:s,trackId:e.trackId}),o=e=>{const s=n(e);r(s)},i=(s,t,r)=>{this.sendError({message:s,request:e},e.trackId,t,r)},a=(e,s)=>{this.sendEvent(e,s)};try{s({requestMessage:e,request:e.payload,store:this.store,error:i,event:a,response:o,createResponseMessage:n,sendResponseMessage:r})}catch(s){i({message:`Error in command handler for '${e.name}'`,requestMessage:e,error:s,stack:s?.stack})}}serverHandleQuery(e){const s=e=>{this.sendMessage?.(e)},r=s=>this.createMessage({name:e.name,type:t.QueryResponse,payload:s,trackId:e.trackId});(0,this.queries[e.name])({requestMessage:e,request:e.payload,store:this.store,error:(s,t,r)=>{this.sendError({message:s,request:e},e.trackId,t,r)},event:(e,s)=>{this.sendEvent(e,s)},response:e=>{const t=r(e);s(t)},createResponseMessage:r,sendResponseMessage:s})}serverHandleEvent(e){(0,this.eventListeners[e.name])({requestMessage:e,request:e.payload,store:this.store,error:s=>{this.sendError({message:s,request:e},e.trackId)},event:(e,s)=>{this.sendEvent(e,s)}})}addCommand(e,s){this.commands[e]=s}addQuery(e,s){this.queries[e]=s}addEventListener(e,s){this.eventListeners[e]=s}}export{g as ClientSideMessageBridgeService,p as InMemoryClientSideServer,o as MapResponseType,l as MessageBridgeServiceBase,r as MessageDirection,t as MessageType,h as SignalRMessageBridgeService,u as WebsocketMessageBridgeService,a as createCommandMessage,d as createEventMessage,i as createMessage,n as createMessageFromDto,c as createQueryMessage}; | ||
//# sourceMappingURL=index.module.js.map |
@@ -1,2 +0,2 @@ | ||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(exports,require("@microsoft/signalr"),require("uuid")):"function"==typeof define&&define.amd?define(["exports","@microsoft/signalr","uuid"],s):s((e||self).messageBridgeJs={},e.signalr,e.uuid)}(this,function(e,s,t){var r,n;function o(s,t=e.MessageDirection.ToClient){return s.isError=s.type===e.MessageType.Error,s.direction??=t,s}function i(s){return{name:s.name,payload:s.payload,type:s.type,direction:s.direction??e.MessageDirection.ToClient,trackId:s.trackId??t.v4(),module:s.module,schema:s.schema,created:(new Date).toISOString(),isError:s.type===e.MessageType.Error}}function a(s){return i({...s,type:e.MessageType.Command})}function c(s){return i({...s,type:e.MessageType.Query})}function d(s){return i({...s,type:e.MessageType.Event})}e.MessageType=void 0,(r=e.MessageType||(e.MessageType={})).Command="Command",r.CommandResponse="CommandResponse",r.Query="Query",r.QueryResponse="QueryResponse",r.Event="Event",r.Error="Error",e.MessageDirection=void 0,(n=e.MessageDirection||(e.MessageDirection={})).ToClient="ToClient",n.ToServer="ToServer";class l{constructor(e){this.wsUri=void 0,this.connected=!1,this.trackedRequestMap={},this.subscribedEventListMap={},this.history=[],this.bridgeErrors=[],this.options={timeout:void 0,allowResponseValueWhenCancelled:!1,keepHistoryForReceivedMessages:!1,keepHistoryForSendingMessages:!1,logger:console?.log??(()=>{}),logParseIncomingMessageError:!0,timeoutFromBridgeOptionsMessage:e=>`Timeout after ${e}ms (BridgeOptions.timeout)`,timeoutFromRequestOptionsMessage:e=>`Timeout after ${e}ms (RequestOptions.timeout)`,logParseIncomingMessageErrorFormat:e=>["Bridge-Error (parse messageReceived):",e],logMessageReceived:!1,logMessageReceivedFormat:e=>["Bridge (messageReceived):",e],logSendingMessage:!1,logSendingMessageFormat:e=>["Bridge (sendingMessage):",e]},this.wsUri=e}setOptions(e){this.options={...this.options,...e}}getTrackedRequestMessage(e){return this.trackedRequestMap[e]?.requestMessage}cancelRequest(e){this.trackedRequestMap[e]&&(this.trackedRequestMap[e].requestMessage.cancelled=!0)}onConnect(){this.connected=!0,this.options.onConnect?.()}onError(e,s){void 0!==e&&this.bridgeErrors.push(e),this.options.onError?.(e,s)}onClose(e,s){void 0!==e&&this.bridgeErrors.push(e),this.connected=!1,this.options.onClose?.(e,s)}setOptionalRequestTimeout({requestMessage:e,timeout:s,onTimeout:t}){let r,n;if(void 0!==s?(r=this.options.timeoutFromRequestOptionsMessage?.(s)??`timeout after ${s}`,n=s):void 0!==this.options.timeout&&(r=this.options.timeoutFromBridgeOptionsMessage?.(this.options.timeout)??`timeout after ${this.options.timeout}`,n=this.options.timeout),void 0!==n)return setTimeout(()=>{e.timedOut=!0,t({reason:r,responseMessage:void 0,request:e.payload,requestMessage:e})},n)}sendMessageTracked(e){if(e.requestMessage.cancelled){let s=!0;if(void 0!==e.requestOptions.sendCancelled?s=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(s=!1),s)return Promise.resolve({request:e.requestMessage.payload,requestMessage:e.requestMessage,cancelled:!0})}return new Promise((s,t)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,t)=>{s(t)},handleError:(e,r)=>{this.options.throwOnTrackedError?t(r):s(r)}})}).finally(()=>{delete this.trackedRequestMap[e.requestMessage.trackId]})}sendMessage(e){const s=void 0;if(e.requestMessage.cancelled){let t=!0;if(void 0!==e.requestOptions.sendCancelled?t=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(t=!1),t)return Promise.resolve(s)}return new Promise((t,r)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,r)=>{t(e?s:r.response)},handleError:(e,n,o)=>{e&&t(s),this.options.avoidThrowOnNonTrackedError?t(o?.payload):r(n)}})})}sendMessagePromiseHandler({handleError:s,handleSuccess:t,requestMessage:r,requestOptions:n}){r.direction=e.MessageDirection.ToServer,this.options.interceptSendMessage&&(r=this.options.interceptSendMessage(r));const o=(e,t)=>{i&&clearTimeout(i);const o={response:void 0,responseMessage:void 0,request:r.payload,requestMessage:r,isError:!0,error:t.reason,errorMessage:t.responseMessage,cancelled:r.cancelled||t.requestMessage?.cancelled||t.responseMessage?.cancelled,timedOut:r.timedOut||t.requestMessage?.timedOut||t.responseMessage?.timedOut};e&&this.options.callOnErrorWhenRequestIsCancelled&&n.callOnErrorWhenRequestIsCancelled||(this.onError(o),n.onError?.(o)),s(e,o,t)},i=this.setOptionalRequestTimeout({requestMessage:r,timeout:n.timeout,onTimeout:e=>{const s=this.handleCancelOptions(n,r);o(s,e)}});this.trackedRequestMap[r.trackId]={successTrack:e=>{const{response:s,cancelled:o}=this.handleCancelResponse(n,r,e),a={response:s,responseMessage:e,requestOptions:n,request:r.payload,requestMessage:r,isError:!1,cancelled:r.cancelled||e.cancelled,timedOut:r.timedOut||e.timedOut};i&&clearTimeout(i),(!o||this.options.callOnSuccessWhenRequestIsCancelled||n.callOnSuccessWhenRequestIsCancelled)&&(this.options.onSuccess?.(a),n.onSuccess?.(a)),t(o,a)},errorTrack:e=>{const{response:s,cancelled:t}=this.handleCancelResponse(n,r,e);o(t,{reason:s,responseMessage:e,request:r.payload,requestMessage:r})},requestMessage:r,requestOptions:n},this.internalSendMessage(r)}handleCancelOptions(e,s,t){let r=!1;void 0!==e.resolveCancelledForNonTracked?r=e.resolveCancelledForNonTracked:this.options.resolveCancelledNonTrackedRequest&&(r=!0);let n=!1;return(t?.cancelled||s.cancelled)&&(n=!0),r&&n&&(n=!1),n}handleCancelResponse(e,s,t){const r=this.handleCancelOptions(e,s,t);let n=t?.payload;return r&&(void 0!==e.allowResponseValueWhenCancelled?!0!==e.allowResponseValueWhenCancelled&&(n=void 0):!0!==this.options.allowResponseValueWhenCancelled&&(n=void 0)),{response:n,cancelled:r}}subscribeEvent({name:e,onEvent:s}){if(Array.isArray(e)){const t=e.map(e=>this.subscribeEvent({name:e,onEvent:s}));return()=>t.forEach(e=>e())}return this.subscribedEventListMap[e]||(this.subscribedEventListMap[e]=[]),this.subscribedEventListMap[e].push(s),()=>{const t=this.subscribedEventListMap[e].findIndex(e=>e===s);this.subscribedEventListMap[e].splice(t,1)}}createTrackedMessage(e){const s=e.requestMessage.trackId;let t={trackId:s,requestMessage:e.requestMessage,requestOptions:e.requestOptions,send:()=>this.sendMessage(e),sendTracked:()=>this.sendMessageTracked(e),cancel:()=>{e?.requestMessage&&(e.requestMessage.cancelled=!0),this.cancelRequest(s)}};return this.options.interceptCreatedMessageOptions&&(t=this.options.interceptCreatedMessageOptions(t)),t}createCommand(e){const s=a(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}createQuery(e){const s=c(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}sendCommand(e){return this.createCommand(e).send()}sendCommandTracked(e){return this.createCommand(e).sendTracked()}sendQuery(e){return this.createQuery(e).send()}sendQueryTracked(e){return this.createQuery(e).sendTracked()}createEvent(s){let t=d(s);t.direction=e.MessageDirection.ToServer;let r={trackId:t.trackId,requestMessage:t,requestOptions:s,cancel:()=>{t&&(t.cancelled=!0)},send:()=>{if(t.cancelled)if(void 0!==s.sendCancelled){if(!s.sendCancelled)return}else if(!this.options.sendCancelledRequest)return;this.options.interceptSendMessage&&(t=this.options.interceptSendMessage(t)),this.internalSendMessage(t)}};return this.options.interceptCreatedEventMessageOptions&&(r=this.options.interceptCreatedEventMessageOptions(r)),r}sendEvent(e){return this.createEvent(e).send()}onMessage(e){let s;try{s="string"==typeof e?JSON.parse(e):e}catch(e){return void this.onError(e)}try{let e=o(s);this.options.interceptReceivedMessage&&(e=this.options.interceptReceivedMessage(e)),this.handleIncomingMessage(e)}catch(e){if(this.onError(e),this.options.logger&&this.options.logParseIncomingMessageError){const t=this.options.logParseIncomingMessageErrorFormat?.(s)??[e];this.options.logger(t)}}}internalSendMessage(e){if(this.options.keepHistoryForSendingMessages&&this.history.push(e),this.options.logger&&this.options.logSendingMessage){let s=!0;if(this.options.logSendingMessageFilter&&(s=!!e.name.match(this.options.logSendingMessageFilter)),s){const s=this.options.logSendingMessageFormat?.(e)??[e];this.options.logger(...s)}}this.options.onSend?.(e),this.sendNetworkMessage(e)}handleIncomingMessage(s){if(this.options.keepHistoryForReceivedMessages&&this.history.push(s),this.options.logger&&this.options.logMessageReceived){let e=!0;if(this.options.logMessageReceivedFilter&&(e=!!s.name.match(this.options.logMessageReceivedFilter)),e){const e=this.options.logMessageReceivedFormat?.(s)??[s];this.options.logger(...e)}}this.options.onMessage?.(s);let t=s.type!==e.MessageType.Error;if(s.type===e.MessageType.Event)return void this.receiveEventMessage(s);const r=this.trackedRequestMap[s.trackId];r&&(s.type===e.MessageType.Error?(r.errorTrack(s),t=!0):r.successTrack(s),delete this.trackedRequestMap[s.trackId]),t||this.onError?.(s)}receiveEventMessage(e){this.subscribedEventListMap[e.name]&&this.subscribedEventListMap[e.name].forEach(s=>s(e.payload,e))}}e.ClientSideMessageBridgeService=class extends l{constructor(...e){super(...e),this.server=void 0}setServer(e){this.server=e}connect(){if(!this.server)throw new Error("No server set");return this.server?.connect(e=>{const s=JSON.parse(JSON.stringify(e));this.onMessage(s),this.onConnect()}),Promise.resolve()}close(){this.onClose()}sendNetworkMessage(e){const s=JSON.parse(JSON.stringify(e));setTimeout(()=>{this.server?.onMessage(s)},10)}},e.InMemoryClientSideServer=class{constructor(){this.store={},this.commands={},this.queries={},this.eventListeners={},this.sendMessage=void 0}saveToLocalStorage(e){localStorage.setItem(e,JSON.stringify(this.store))}loadFromLocalStorage(e){const s=localStorage.getItem(e);s&&(this.store=JSON.parse(s))}connect(e){this.sendMessage=e}sendError(s,t,r,n){const o=i({trackId:t,type:e.MessageType.Error,name:"Error",payload:s,direction:e.MessageDirection.ToClient,cancelled:r,timedOut:n});this.sendMessage?.(o)}createMessage(s){return i({...s,direction:e.MessageDirection.ToClient})}sendResponse(e){const s=this.createMessage(e);this.sendMessage?.(s)}sendEvent(s,t){const r=i({type:e.MessageType.Event,name:s,payload:t,direction:e.MessageDirection.ToClient});this.sendMessage?.(r)}onMessage(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(s){return this.sendError({message:`Error parsing message: ${s}`,request:e,error:s,stack:s?.stack}),void console.error("Error parsing message",s)}if("Command"===e.type){if(!this.commands[e.name])return void this.sendError({message:`Command ${e.name} not found (Register it with addCommand)`,request:e},e.trackId);this.serverHandleCommand(e)}if("Query"===e.type){if(!this.queries[e.name])return void this.sendError({message:`Query ${e.name} not found (Register it with addQuery)`,request:e},e.trackId);this.serverHandleQuery(e)}if("Event"===e.type){if(!this.eventListeners[e.name])return void this.sendError({message:`Event ${e.name} not found (Register it with addEvent)`,request:e},e.trackId);this.serverHandleEvent(e)}}serverHandleCommand(s){const t=this.commands[s.name],r=e=>{this.sendMessage?.(e)},n=t=>this.createMessage({name:s.name,type:e.MessageType.CommandResponse,payload:t,trackId:s.trackId}),o=e=>{const s=n(e);r(s)},i=(e,t,r)=>{this.sendError({message:e,request:s},s.trackId,t,r)},a=(e,s)=>{this.sendEvent(e,s)};try{t({requestMessage:s,request:s.payload,store:this.store,error:i,event:a,response:o,createResponseMessage:n,sendResponseMessage:r})}catch(e){i({message:`Error in command handler for '${s.name}'`,requestMessage:s,error:e,stack:e?.stack})}}serverHandleQuery(s){const t=e=>{this.sendMessage?.(e)},r=t=>this.createMessage({name:s.name,type:e.MessageType.QueryResponse,payload:t,trackId:s.trackId});(0,this.queries[s.name])({requestMessage:s,request:s.payload,store:this.store,error:(e,t,r)=>{this.sendError({message:e,request:s},s.trackId,t,r)},event:(e,s)=>{this.sendEvent(e,s)},response:e=>{const s=r(e);t(s)},createResponseMessage:r,sendResponseMessage:t})}serverHandleEvent(e){(0,this.eventListeners[e.name])({requestMessage:e,request:e.payload,store:this.store,error:s=>{this.sendError({message:s,request:e},e.trackId)},event:(e,s)=>{this.sendEvent(e,s)}})}addCommand(e,s){this.commands[e]=s}addQuery(e,s){this.queries[e]=s}addEventListener(e,s){this.eventListeners[e]=s}},e.MessageBridgeServiceBase=l,e.SignalRMessageBridgeService=class extends l{constructor(...e){super(...e),this.connection=void 0}connect(e={}){if(this.connection=(new s.HubConnectionBuilder).withUrl(this.wsUri,e).withAutomaticReconnect().build(),!this.connection)throw new Error("Failed to create SignalR connection");return this.connection.on("ReceiveMessage",e=>{this.onMessage(e)}),this.connection.onclose(e=>{this.onClose(e)}),this.connection.start().then(()=>{this.onConnect()}).catch(e=>{this.onError(e)})}close(){this.connection?.stop(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.connection?.invoke("SendMessage",s).catch(e=>(this.onError(e),console.error(e.toString())))}},e.WebsocketMessageBridgeService=class extends l{constructor(...e){super(...e),this.socket=void 0,this.connectedCallback=void 0}connect(){return this.socket=new WebSocket(this.wsUri),this.socket.addEventListener("message",e=>{this.onMessage(e.data)}),this.socket.addEventListener("close",e=>{this.onClose(e.reason,e)}),this.socket.addEventListener("error",e=>{this.onError(e,e)}),new Promise((e,s)=>{this.socket?.addEventListener("open",s=>{this.onConnect(),e()})})}close(){this.socket?.close(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.socket?.send(s)}},e.createCommandMessage=a,e.createEventMessage=d,e.createMessage=i,e.createMessageFromDto=o,e.createQueryMessage=c}); | ||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(exports,require("@microsoft/signalr"),require("uuid")):"function"==typeof define&&define.amd?define(["exports","@microsoft/signalr","uuid"],s):s((e||self).messageBridgeJs={},e.signalr,e.uuid)}(this,function(e,s,t){var r,n;function o(s,t=e.MessageDirection.ToClient){return s.isError=s.type===e.MessageType.Error,s.direction??=t,s}function i(s){return{name:s.name,payload:s.payload,type:s.type,direction:s.direction??e.MessageDirection.ToClient,trackId:s.trackId??t.v4(),module:s.module,schema:s.schema,created:(new Date).toISOString(),isError:s.type===e.MessageType.Error}}function a(s){return i({...s,type:e.MessageType.Command})}function c(s){return i({...s,type:e.MessageType.Query})}function d(s){return i({...s,type:e.MessageType.Event})}e.MessageType=void 0,(r=e.MessageType||(e.MessageType={})).Command="Command",r.CommandResponse="CommandResponse",r.Query="Query",r.QueryResponse="QueryResponse",r.Event="Event",r.Error="Error",e.MessageDirection=void 0,(n=e.MessageDirection||(e.MessageDirection={})).ToClient="ToClient",n.ToServer="ToServer";class l{constructor(e){this.wsUri=void 0,this.connected=!1,this.trackedRequestMap={},this.subscribedEventListMap={},this.history=[],this.bridgeErrors=[],this.options={timeout:void 0,allowResponseValueWhenCancelled:!1,keepHistoryForReceivedMessages:!1,keepHistoryForSendingMessages:!1,logger:console?.log??(()=>{}),logParseIncomingMessageError:!0,timeoutFromBridgeOptionsMessage:e=>`Timeout after ${e}ms (BridgeOptions.timeout)`,timeoutFromRequestOptionsMessage:e=>`Timeout after ${e}ms (RequestOptions.timeout)`,logParseIncomingMessageErrorFormat:e=>["Bridge-Error (parse messageReceived):",e],logMessageReceived:!1,logMessageReceivedFormat:e=>["Bridge (messageReceived):",e],logSendingMessage:!1,logSendingMessageFormat:e=>["Bridge (sendingMessage):",e]},this.wsUri=e}setOptions(e){this.options={...this.options,...e}}getTrackedRequestMessage(e){return this.trackedRequestMap[e]?.requestMessage}cancelRequest(e){this.trackedRequestMap[e]&&(this.trackedRequestMap[e].requestMessage.cancelled=!0)}onConnect(){this.connected=!0,this.options.onConnect?.()}onError(e,s){void 0!==e&&this.bridgeErrors.push(e),this.options.onError?.(e,s)}onClose(e,s){void 0!==e&&this.bridgeErrors.push(e),this.connected=!1,this.options.onClose?.(e,s)}setOptionalRequestTimeout({requestMessage:e,timeout:s,onTimeout:t}){let r,n;if(void 0!==s?(r=this.options.timeoutFromRequestOptionsMessage?.(s)??`timeout after ${s}`,n=s):void 0!==this.options.timeout&&(r=this.options.timeoutFromBridgeOptionsMessage?.(this.options.timeout)??`timeout after ${this.options.timeout}`,n=this.options.timeout),void 0!==n)return setTimeout(()=>{e.timedOut=!0,t({reason:r,responseMessage:void 0,request:e.payload,requestMessage:e})},n)}sendMessageTracked(e){if(e.requestMessage.cancelled){let s=!0;if(void 0!==e.requestOptions.sendCancelled?s=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(s=!1),s)return Promise.resolve({request:e.requestMessage.payload,requestMessage:e.requestMessage,cancelled:!0})}return new Promise((s,t)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,t)=>{s(t)},handleError:(e,r)=>{this.options.throwOnTrackedError?t(r):s(r)}})}).finally(()=>{delete this.trackedRequestMap[e.requestMessage.trackId]})}sendMessage(e){const s=void 0;if(e.requestMessage.cancelled){let t=!0;if(void 0!==e.requestOptions.sendCancelled?t=!e.requestOptions.sendCancelled:this.options.sendCancelledRequest&&(t=!1),t)return Promise.resolve(s)}return new Promise((t,r)=>{this.sendMessagePromiseHandler({...e,handleSuccess:(e,r)=>{t(e?s:r.response)},handleError:(e,n,o)=>{e&&t(s),this.options.avoidThrowOnNonTrackedError?t(o?.payload):r(n)}})})}sendMessagePromiseHandler({handleError:s,handleSuccess:t,requestMessage:r,requestOptions:n}){r.direction=e.MessageDirection.ToServer,this.options.interceptSendMessage&&(r=this.options.interceptSendMessage(r));const o=(e,t)=>{i&&clearTimeout(i);const o={response:void 0,responseMessage:void 0,request:r.payload,requestMessage:r,isError:!0,error:t.reason,errorMessage:t.responseMessage,cancelled:r.cancelled||t.requestMessage?.cancelled||t.responseMessage?.cancelled,timedOut:r.timedOut||t.requestMessage?.timedOut||t.responseMessage?.timedOut};e&&this.options.callOnErrorWhenRequestIsCancelled&&n.callOnErrorWhenRequestIsCancelled||(this.onError(o),n.onError?.(o)),s(e,o,t)},i=this.setOptionalRequestTimeout({requestMessage:r,timeout:n.timeout,onTimeout:e=>{const s=this.handleCancelOptions(n,r);o(s,e)}});this.trackedRequestMap[r.trackId]={successTrack:e=>{const{response:s,cancelled:o}=this.handleCancelResponse(n,r,e),a={response:s,responseMessage:e,requestOptions:n,request:r.payload,requestMessage:r,isError:!1,cancelled:r.cancelled||e.cancelled,timedOut:r.timedOut||e.timedOut};i&&clearTimeout(i),(!o||this.options.callOnSuccessWhenRequestIsCancelled||n.callOnSuccessWhenRequestIsCancelled)&&(this.options.onSuccess?.(a),n.onSuccess?.(a)),t(o,a)},errorTrack:e=>{const{response:s,cancelled:t}=this.handleCancelResponse(n,r,e);o(t,{reason:s,responseMessage:e,request:r.payload,requestMessage:r})},requestMessage:r,requestOptions:n},this.internalSendMessage(r)}handleCancelOptions(e,s,t){let r=!1;void 0!==e.resolveCancelledForNonTracked?r=e.resolveCancelledForNonTracked:this.options.resolveCancelledNonTrackedRequest&&(r=!0);let n=!1;return(t?.cancelled||s.cancelled)&&(n=!0),r&&n&&(n=!1),n}handleCancelResponse(e,s,t){const r=this.handleCancelOptions(e,s,t);let n=t?.payload;return r&&(void 0!==e.allowResponseValueWhenCancelled?!0!==e.allowResponseValueWhenCancelled&&(n=void 0):!0!==this.options.allowResponseValueWhenCancelled&&(n=void 0)),{response:n,cancelled:r}}subscribeEvent({name:e,onEvent:s}){if(Array.isArray(e)){const t=e.map(e=>this.subscribeEvent({name:e,onEvent:s}));return()=>t.forEach(e=>e())}return this.subscribedEventListMap[e]||(this.subscribedEventListMap[e]=[]),this.subscribedEventListMap[e].push(s),()=>{const t=this.subscribedEventListMap[e].findIndex(e=>e===s);this.subscribedEventListMap[e].splice(t,1)}}createTrackedMessage(e){const s=e.requestMessage.trackId;let t={trackId:s,requestMessage:e.requestMessage,requestOptions:e.requestOptions,send:()=>this.sendMessage(e),sendTracked:()=>this.sendMessageTracked(e),cancel:()=>{e?.requestMessage&&(e.requestMessage.cancelled=!0),this.cancelRequest(s)}};return this.options.interceptCreatedMessageOptions&&(t=this.options.interceptCreatedMessageOptions(t)),t}createCommand(e){const s=a(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}createQuery(e){const s=c(e);return this.createTrackedMessage({requestMessage:s,requestOptions:e})}sendCommand(e){return this.createCommand(e).send()}sendCommandTracked(e){return this.createCommand(e).sendTracked()}sendQuery(e){return this.createQuery(e).send()}sendQueryTracked(e){return this.createQuery(e).sendTracked()}createEvent(s){let t=d(s);t.direction=e.MessageDirection.ToServer;let r={trackId:t.trackId,requestMessage:t,requestOptions:s,cancel:()=>{t&&(t.cancelled=!0)},send:()=>{if(t.cancelled)if(void 0!==s.sendCancelled){if(!s.sendCancelled)return}else if(!this.options.sendCancelledRequest)return;this.options.interceptSendMessage&&(t=this.options.interceptSendMessage(t)),this.internalSendMessage(t)}};return this.options.interceptCreatedEventMessageOptions&&(r=this.options.interceptCreatedEventMessageOptions(r)),r}sendEvent(e){return this.createEvent(e).send()}onMessage(e){let s;try{s="string"==typeof e?JSON.parse(e):e}catch(e){return void this.onError(e)}try{let e=o(s);this.options.interceptReceivedMessage&&(e=this.options.interceptReceivedMessage(e)),this.handleIncomingMessage(e)}catch(e){if(this.onError(e),this.options.logger&&this.options.logParseIncomingMessageError){const t=this.options.logParseIncomingMessageErrorFormat?.(s)??[e];this.options.logger(t)}}}internalSendMessage(e){if(this.options.keepHistoryForSendingMessages&&this.history.push(e),this.options.logger&&this.options.logSendingMessage){let s=!0;if(this.options.logSendingMessageFilter&&(s=!!e.name.match(this.options.logSendingMessageFilter)),s){const s=this.options.logSendingMessageFormat?.(e)??[e];this.options.logger(...s)}}this.options.onSend?.(e),this.sendNetworkMessage(e)}handleIncomingMessage(s){if(this.options.keepHistoryForReceivedMessages&&this.history.push(s),this.options.logger&&this.options.logMessageReceived){let e=!0;if(this.options.logMessageReceivedFilter&&(e=!!s.name.match(this.options.logMessageReceivedFilter)),e){const e=this.options.logMessageReceivedFormat?.(s)??[s];this.options.logger(...e)}}this.options.onMessage?.(s);let t=s.type!==e.MessageType.Error;if(s.type===e.MessageType.Event)return void this.receiveEventMessage(s);const r=this.trackedRequestMap[s.trackId];r&&(s.type===e.MessageType.Error?(r.errorTrack(s),t=!0):r.successTrack(s),delete this.trackedRequestMap[s.trackId]),t||this.onError?.(s)}receiveEventMessage(e){this.subscribedEventListMap[e.name]&&this.subscribedEventListMap[e.name].forEach(s=>s(e.payload,e))}}e.ClientSideMessageBridgeService=class extends l{constructor(...e){super(...e),this.server=void 0}setServer(e){this.server=e}connect(){if(!this.server)throw new Error("No server set");return this.server?.connect(e=>{const s=JSON.parse(JSON.stringify(e));this.onMessage(s),this.onConnect()}),Promise.resolve()}close(){this.onClose()}sendNetworkMessage(e){const s=JSON.parse(JSON.stringify(e));setTimeout(()=>{this.server?.onMessage(s)},10)}},e.InMemoryClientSideServer=class{constructor(){this.store={},this.commands={},this.queries={},this.eventListeners={},this.sendMessage=void 0}saveToLocalStorage(e){localStorage.setItem(e,JSON.stringify(this.store))}loadFromLocalStorage(e){const s=localStorage.getItem(e);s&&(this.store=JSON.parse(s))}connect(e){this.sendMessage=e}sendError(s,t,r,n){const o=i({trackId:t,type:e.MessageType.Error,name:"Error",payload:s,direction:e.MessageDirection.ToClient,cancelled:r,timedOut:n});this.sendMessage?.(o)}createMessage(s){return i({...s,direction:e.MessageDirection.ToClient})}sendResponse(e){const s=this.createMessage(e);this.sendMessage?.(s)}sendEvent(s,t){const r=i({type:e.MessageType.Event,name:s,payload:t,direction:e.MessageDirection.ToClient});this.sendMessage?.(r)}onMessage(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(s){return this.sendError({message:`Error parsing message: ${s}`,request:e,error:s,stack:s?.stack}),void console.error("Error parsing message",s)}if("Command"===e.type){if(!this.commands[e.name])return void this.sendError({message:`Command ${e.name} not found (Register it with addCommand)`,request:e},e.trackId);this.serverHandleCommand(e)}if("Query"===e.type){if(!this.queries[e.name])return void this.sendError({message:`Query ${e.name} not found (Register it with addQuery)`,request:e},e.trackId);this.serverHandleQuery(e)}if("Event"===e.type){if(!this.eventListeners[e.name])return void this.sendError({message:`Event ${e.name} not found (Register it with addEvent)`,request:e},e.trackId);this.serverHandleEvent(e)}}serverHandleCommand(s){const t=this.commands[s.name],r=e=>{this.sendMessage?.(e)},n=t=>this.createMessage({name:s.name,type:e.MessageType.CommandResponse,payload:t,trackId:s.trackId}),o=e=>{const s=n(e);r(s)},i=(e,t,r)=>{this.sendError({message:e,request:s},s.trackId,t,r)},a=(e,s)=>{this.sendEvent(e,s)};try{t({requestMessage:s,request:s.payload,store:this.store,error:i,event:a,response:o,createResponseMessage:n,sendResponseMessage:r})}catch(e){i({message:`Error in command handler for '${s.name}'`,requestMessage:s,error:e,stack:e?.stack})}}serverHandleQuery(s){const t=e=>{this.sendMessage?.(e)},r=t=>this.createMessage({name:s.name,type:e.MessageType.QueryResponse,payload:t,trackId:s.trackId});(0,this.queries[s.name])({requestMessage:s,request:s.payload,store:this.store,error:(e,t,r)=>{this.sendError({message:e,request:s},s.trackId,t,r)},event:(e,s)=>{this.sendEvent(e,s)},response:e=>{const s=r(e);t(s)},createResponseMessage:r,sendResponseMessage:t})}serverHandleEvent(e){(0,this.eventListeners[e.name])({requestMessage:e,request:e.payload,store:this.store,error:s=>{this.sendError({message:s,request:e},e.trackId)},event:(e,s)=>{this.sendEvent(e,s)}})}addCommand(e,s){this.commands[e]=s}addQuery(e,s){this.queries[e]=s}addEventListener(e,s){this.eventListeners[e]=s}},e.MapResponseType=function(s){switch(s){case e.MessageType.Command:return e.MessageType.CommandResponse;case e.MessageType.Query:return e.MessageType.QueryResponse;default:return s}},e.MessageBridgeServiceBase=l,e.SignalRMessageBridgeService=class extends l{constructor(...e){super(...e),this.connection=void 0}connect(e={}){if(this.connection=(new s.HubConnectionBuilder).withUrl(this.wsUri,e).withAutomaticReconnect().build(),!this.connection)throw new Error("Failed to create SignalR connection");return this.connection.on("ReceiveMessage",e=>{this.onMessage(e)}),this.connection.onclose(e=>{this.onClose(e)}),this.connection.start().then(()=>{this.onConnect()}).catch(e=>{this.onError(e)})}close(){this.connection?.stop(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.connection?.invoke("SendMessage",s).catch(e=>(this.onError(e),console.error(e.toString())))}},e.WebsocketMessageBridgeService=class extends l{constructor(...e){super(...e),this.socket=void 0,this.connectedCallback=void 0}connect(){return this.socket=new WebSocket(this.wsUri),this.socket.addEventListener("message",e=>{this.onMessage(e.data)}),this.socket.addEventListener("close",e=>{this.onClose(e.reason,e)}),this.socket.addEventListener("error",e=>{this.onError(e,e)}),new Promise((e,s)=>{this.socket?.addEventListener("open",s=>{this.onConnect(),e()})})}close(){this.socket?.close(),this.onClose()}sendNetworkMessage(e){const s=JSON.stringify(e);this.socket?.send(s)}},e.createCommandMessage=a,e.createEventMessage=d,e.createMessage=i,e.createMessageFromDto=o,e.createQueryMessage=c}); | ||
//# sourceMappingURL=index.umd.js.map |
@@ -1,3 +0,4 @@ | ||
import { Message, MessageDirection, OmitAndOptional } from "./MessageBridgeTypes"; | ||
import { Message, MessageDirection, MessageType, OmitAndOptional } from "./MessageBridgeTypes"; | ||
export declare function createMessageFromDto<TPayload = any, TSchema = any>(msg: Message<TPayload, TSchema>, direction?: MessageDirection): Message<TPayload, TSchema>; | ||
export declare function MapResponseType(type: MessageType): MessageType.CommandResponse | MessageType.QueryResponse | MessageType.Event | MessageType.Error; | ||
export declare function createMessage<TPayload = any | undefined, TSchema = any>(opt: OmitAndOptional<Message<TPayload, TSchema>, "created" | "isError", "trackId" | "direction">): Message<TPayload, TSchema>; | ||
@@ -4,0 +5,0 @@ export declare function createCommandMessage<TRequest = any, TSchema = any>(opt: OmitAndOptional<Message<TRequest, TSchema>, "created" | "isError" | "type", "trackId" | "direction">): Message<TRequest, TSchema>; |
{ | ||
"name": "message-bridge-js", | ||
"version": "0.9.3", | ||
"version": "0.9.4", | ||
"homepage": "https://github.com/alfnielsen/MessageBridgeJS", | ||
@@ -5,0 +5,0 @@ "repository": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
353024
516