cbcore-ts 1.0.62 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiledScripts/CBDataInterfaces.d.ts +29 -0
- package/compiledScripts/CBDataInterfaces.js.map +2 -2
- package/compiledScripts/CBSocketCallbackHolder.d.ts +17 -1
- package/compiledScripts/CBSocketCallbackHolder.js +32 -3
- package/compiledScripts/CBSocketCallbackHolder.js.map +3 -3
- package/compiledScripts/CBSocketClient.d.ts +39 -3
- package/compiledScripts/CBSocketClient.js +39 -4
- package/compiledScripts/CBSocketClient.js.map +2 -2
- package/package.json +1 -1
- package/scripts/CBDataInterfaces.ts +35 -25
- package/scripts/CBSocketCallbackHolder.ts +70 -30
- package/scripts/CBSocketClient.ts +114 -23
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/CBSocketClient.ts"],
|
|
4
|
-
"sourcesContent": ["import { io, ManagerOptions, Socket, SocketOptions } from \"socket.io-client\"\nimport { FIRST_OR_NIL, IF, IS, IS_NIL, IS_NOT, MAKE_ID, nil, NO, RETURNER, UIObject, YES } from \"../../uicore-ts\"\nimport { CBCore } from \"./CBCore\"\nimport {\n CBSocketHandshakeInitMessage,\n CBSocketHandshakeResponseMessage,\n CBSocketMessage,\n CBSocketMessageCompletionFunction,\n CBSocketMessageHandlerFunction,\n CBSocketMessageSendResponseFunction,\n CBSocketMultipleMessage,\n CBSocketMultipleMessagecompletionFunction,\n CBSocketMultipleMessageObject,\n SocketClientInterface\n} from \"./CBDataInterfaces\"\nimport { CBSocketCallbackHolder } from \"./CBSocketCallbackHolder\"\n\n\ndeclare interface CBSocketClientMessageToBeSent {\n \n key: string;\n message: any;\n \n inResponseToMessage: CBSocketMessage<any>;\n keepWaitingForResponses: boolean;\n \n isBoundToUserWithID: string;\n \n completionPolicy: string;\n \n didSendFunction?: () => void;\n \n completion: CBSocketMessageCompletionFunction;\n \n}\n\n\ndeclare interface CBSocketClientErrorMessage {\n \n _isCBSocketErrorMessage: boolean;\n \n messageData: any;\n \n}\n\n\ntype FilterConditionally<Source, Condition> = Pick<Source, { [K in keyof Source]: Source[K] extends Condition ? K : never }[keyof Source]>;\n\n\nexport function IS_SOCKET_ERROR(object: any): object is CBSocketClientErrorMessage {\n \n const result = (IS(object) && object._isCBSocketErrorMessage)\n \n return result\n \n}\n\nexport function IS_NOT_SOCKET_ERROR(object: any) {\n \n return !IS_SOCKET_ERROR(object)\n \n}\n\n\nexport class CBSocketClient extends UIObject {\n \n _socket: Socket\n _isConnectionEstablished = NO\n \n _collectMessagesToSendLater = NO\n \n _messagesToBeSent: CBSocketClientMessageToBeSent[] = []\n \n static _sharedInstance: CBSocketClient\n \n _core: CBCore\n \n _subscribedKeys: {\n [x: string]: boolean\n } = {}\n \n _callbackHolder = new CBSocketCallbackHolder(this)\n \n static responseMessageKey = \"CBSocketResponseMessage\"\n static multipleMessageKey = \"CBSocketMultipleMessage\"\n \n \n static disconnectionMessage: CBSocketClientErrorMessage = {\n \n _isCBSocketErrorMessage: YES,\n \n messageData: \"Server disconnected\"\n \n }\n \n \n static timeoutMessage: CBSocketClientErrorMessage = {\n \n _isCBSocketErrorMessage: YES,\n \n messageData: \"Request timed out\"\n \n }\n \n \n /**\n * How long (in milliseconds) to wait for a server response before treating\n * the request as failed. Set to 0 to disable timeouts entirely.\n * Default: 30 000 ms (30 seconds).\n */\n requestTimeoutMs: number = 30_000\n \n \n constructor(core: CBCore) {\n \n super()\n \n this._core = core\n this._socket = io()\n \n this.socket.on(\"connect\", () => {\n \n console.log(\"Socket.io connected to server. clientID = \", this.socket, \" socketID = \", this.socket)\n \n this.sendUnsentMessages()\n \n })\n \n \n this._callbackHolder = new CBSocketCallbackHolder(this, this._callbackHolder)\n \n this.socket.on(\n \"CBSocketWelcomeMessage\",\n (message: CBSocketMessage<{ userProfile?: Record<string, string> }>) => {\n \n core.userProfile = message.messageData.userProfile\n \n this._isConnectionEstablished = YES\n \n this.sendUnsentMessages()\n \n }\n )\n \n this.socket.on(\"disconnect\", () => {\n \n console.log(\"Socket.io disconnected from server. clientID = \", this.socket)\n \n this._isConnectionEstablished = NO\n this._callbackHolder.isValid = NO\n this._callbackHolder.triggerDisconnectHandlers()\n \n \n })\n \n \n this.socket.on(\"CBPerformReconnect\", (message?: string) => {\n \n console.log(\"Performing socket reconnection.\")\n \n core.reloadSocketConnection()\n if (message) {\n this._core.dialogViewShowerClass.alert(message)\n }\n \n \n })\n \n \n this._socket.on(\n CBSocketClient.responseMessageKey,\n (message: CBSocketMessage<any>) => {\n \n this.didReceiveMessageForKey(CBSocketClient.responseMessageKey, message)\n \n }\n )\n \n this._socket.on(\n CBSocketClient.multipleMessageKey,\n (message: CBSocketMessage<CBSocketMultipleMessageObject[]>) => {\n \n console.log(\"Received \" + message.messageData.length + \" messages.\")\n // @ts-ignore\n if (document.cbsocketclientlogmessages) {\n console.log(message.messageData)\n }\n this.didReceiveMessageForKey(CBSocketClient.multipleMessageKey, message)\n \n }\n )\n \n \n }\n \n \n get socket() {\n return this._socket\n }\n \n \n cancelUnsentMessages(messagesToCancel: CBSocketClientMessageToBeSent[]) {\n \n this._messagesToBeSent = this._messagesToBeSent.filter((\n messageObject: CBSocketClientMessageToBeSent,\n index: number,\n array: CBSocketClientMessageToBeSent[]\n ) => !messagesToCancel.contains(messageObject))\n \n }\n \n \n sendUnsentMessages(receiveResponsesTogether = NO, completion?: CBSocketMultipleMessagecompletionFunction) {\n \n if (!this._isConnectionEstablished || this._collectMessagesToSendLater) {\n \n return\n \n }\n \n const groupedMessages: CBSocketMultipleMessageObject<any>[] = []\n const didSendFunctions: (() => void)[] = []\n \n \n this._messagesToBeSent.copy().forEach((messageToBeSentObject: CBSocketClientMessageToBeSent) => {\n \n if (this._isConnectionEstablished) {\n \n var message = messageToBeSentObject.message\n if (IS_NOT(message)) {\n message = \"\"\n }\n \n const identifier = MAKE_ID()\n \n const completion = messageToBeSentObject.completion\n \n const messageObject: CBSocketMessage<any> = {\n \n messageData: message,\n identifier: identifier,\n keepWaitingForResponses: messageToBeSentObject.keepWaitingForResponses,\n inResponseToIdentifier: messageToBeSentObject.inResponseToMessage.identifier,\n completionPolicy: messageToBeSentObject.completionPolicy\n \n }\n \n const shouldSendMessage = this._callbackHolder.socketShouldSendMessage(\n messageToBeSentObject.key,\n messageObject,\n messageToBeSentObject.completionPolicy,\n completion\n )\n \n if (shouldSendMessage) {\n \n \n groupedMessages.push({\n \n key: messageToBeSentObject.key,\n message: messageObject\n \n })\n \n \n }\n \n didSendFunctions.push(messageToBeSentObject.didSendFunction!)\n \n \n }\n \n })\n \n \n this._messagesToBeSent = []\n \n if (IS_NOT(groupedMessages.length)) {\n \n return\n \n }\n \n if (groupedMessages.length == 1) {\n \n console.log(\"sending 1 unsent message.\")\n \n }\n else {\n \n console.log(\"Sending \" + groupedMessages.length + \" unsent messages.\")\n \n }\n \n \n const messageObject: CBSocketMultipleMessage = {\n \n messageData: groupedMessages,\n identifier: MAKE_ID(),\n completionPolicy: CBSocketClient.completionPolicy.all,\n \n shouldGroupResponses: receiveResponsesTogether\n \n }\n \n //if (receiveResponsesTogether) {\n \n this._callbackHolder.socketWillSendMultipleMessage(messageObject, completion)\n \n //}\n \n // @ts-ignore\n if (document.cbsocketclientlogmessages) {\n console.log(\n \"CB socket client is sending multiple messages. [\",\n groupedMessages.everyElement.key.UI_elementValues?.join(\", \"), \"] \",\n messageObject\n )\n }\n \n this.socket.emit(CBSocketClient.multipleMessageKey, messageObject)\n \n \n didSendFunctions.forEach((didSendFunction, index, array) => {\n didSendFunction()\n })\n \n }\n \n \n static completionPolicy = {\n \n \"all\": \"all\",\n \"allDifferent\": \"allDifferent\",\n \"first\": \"first\",\n \"last\": \"last\",\n \"firstAndLast\": \"firstAndLast\",\n \"firstAndLastIfDifferent\": \"firstAndLastIfDifferent\",\n \"directOnly\": \"directOnly\",\n \"firstOnly\": \"firstOnly\",\n \"storedOrFirst\": \"storedOrFirst\"\n \n } as const\n \n \n sendUserBoundMessageForKeyWithPolicy(\n key: keyof SocketClientInterface,\n message: any,\n completionPolicy: keyof typeof CBSocketClient.completionPolicy,\n completion?: CBSocketMessageCompletionFunction\n ) {\n \n \n this._sendMessageForKey(key as string, message, undefined, NO, completionPolicy, YES, nil, completion)\n \n }\n \n sendUserBoundMessageForKey(\n key: keyof SocketClientInterface,\n message: any,\n completion?: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(key as string, message, undefined, NO, undefined, YES, nil, completion)\n \n }\n \n sendMessageForKeyWithPolicy(\n key: keyof SocketClientInterface,\n message: any,\n completionPolicy: keyof typeof CBSocketClient.completionPolicy,\n completion?: CBSocketMessageCompletionFunction\n ) {\n \n \n this._sendMessageForKey(key as string, message, undefined, NO, completionPolicy, NO, nil, completion)\n \n }\n \n sendMessageForKey(key: keyof SocketClientInterface, message: any, completion?: CBSocketMessageCompletionFunction) {\n \n this._sendMessageForKey(key as string, message, undefined, NO, undefined, NO, nil, completion)\n \n }\n \n \n resultForMessageForKey(\n key: keyof SocketClientInterface,\n message: any,\n completionPolicy?: keyof typeof CBSocketClient.completionPolicy,\n isUserBound = NO\n ) {\n \n const result = new Promise<{\n \n responseMessage: any,\n result: any,\n errorResult: any,\n \n respondWithMessage: CBSocketMessageSendResponseFunction\n \n }>((resolve, reject) => {\n \n this._sendMessageForKey(\n key as string,\n message,\n undefined,\n NO,\n completionPolicy,\n isUserBound,\n nil,\n (responseMessage, respondWithMessage) => resolve({\n \n responseMessage: responseMessage,\n result: IF(IS_NOT_SOCKET_ERROR(responseMessage))(() => responseMessage).ELSE(RETURNER(undefined)),\n errorResult: IF(IS_SOCKET_ERROR(responseMessage))(() => responseMessage).ELSE(RETURNER(undefined)),\n \n respondWithMessage: respondWithMessage\n \n })\n )\n \n })\n \n return result\n \n }\n \n \n _sendMessageForKey(\n key: string,\n message: any,\n inResponseToMessage: CBSocketMessage<any> = {} as any,\n keepMessageConnectionOpen = NO,\n completionPolicy: keyof typeof CBSocketClient.completionPolicy = CBSocketClient.completionPolicy.directOnly,\n isUserBound = NO,\n didSendFunction: () => void = nil,\n completion: CBSocketMessageCompletionFunction = nil\n ) {\n \n if (IS_NIL(message)) {\n \n message = \"\"\n \n }\n \n if (this._isConnectionEstablished && !this._collectMessagesToSendLater) {\n \n const identifier = MAKE_ID()\n \n const messageObject: CBSocketMessage<any> = {\n \n messageData: message,\n identifier: identifier,\n keepWaitingForResponses: keepMessageConnectionOpen,\n inResponseToIdentifier: inResponseToMessage.identifier,\n completionPolicy: completionPolicy\n \n }\n \n const shouldSendMessage = this._callbackHolder.socketShouldSendMessage(\n key,\n messageObject,\n completionPolicy,\n completion\n )\n \n if (shouldSendMessage) {\n \n // @ts-ignore\n if (document.cbsocketclientlogmessages) {\n console.log(\n \"CB socket client is sending message. [\", key, \"] \",\n messageObject\n )\n }\n \n this.socket.emit(key, messageObject)\n \n }\n \n didSendFunction()\n \n }\n else {\n \n this._messagesToBeSent.push({\n \n key: key,\n message: message,\n inResponseToMessage: inResponseToMessage,\n keepWaitingForResponses: keepMessageConnectionOpen,\n completionPolicy: completionPolicy,\n isBoundToUserWithID: IF(isUserBound)(RETURNER(FIRST_OR_NIL(CBCore.sharedInstance.userProfile?._id)))(),\n didSendFunction: didSendFunction,\n completion: completion\n \n })\n \n return this._messagesToBeSent.lastElement\n \n }\n \n }\n \n \n sendMessagesAsGroup<FunctionReturnType extends object>(functionToCall: () => FunctionReturnType) {\n \n const collectMessagesToSendLater = this._collectMessagesToSendLater\n \n this._collectMessagesToSendLater = YES\n \n var result = functionToCall()\n \n this._collectMessagesToSendLater = collectMessagesToSendLater\n \n this.sendUnsentMessages()\n \n return result\n \n }\n \n sendAndReceiveMessagesAsGroup<FunctionReturnType extends object>(\n functionToCall: () => FunctionReturnType,\n completion?: CBSocketMultipleMessagecompletionFunction\n ) {\n \n const collectMessagesToSendLater = this._collectMessagesToSendLater\n \n this._collectMessagesToSendLater = YES\n \n var result = functionToCall()\n \n this._collectMessagesToSendLater = collectMessagesToSendLater\n \n this.sendUnsentMessages(YES, completion)\n \n return result\n \n }\n \n \n didReceiveMessageForKey(key: string, message: CBSocketMessage<any>) {\n \n \n const sendResponseFunction: CBSocketMessageSendResponseFunction = function (\n this: CBSocketClient,\n responseMessage: any,\n completion: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(\n CBSocketClient.responseMessageKey,\n responseMessage,\n message,\n NO,\n undefined,\n NO,\n nil,\n completion\n )\n \n }.bind(this) as any\n \n sendResponseFunction.sendIntermediateResponse = function (\n this: CBSocketClient,\n updateMessage: any,\n completion: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(\n CBSocketClient.responseMessageKey,\n updateMessage,\n message,\n YES,\n undefined,\n NO,\n nil,\n completion\n )\n \n }.bind(this)\n \n const sendUserBoundResponseFunction: CBSocketMessageSendResponseFunction = function (\n this: CBSocketClient,\n responseMessage: any,\n completion: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(\n CBSocketClient.responseMessageKey,\n responseMessage,\n message,\n NO,\n undefined,\n YES,\n nil,\n completion\n )\n \n }.bind(this) as any\n \n sendUserBoundResponseFunction.sendIntermediateResponse = function (\n this: CBSocketClient,\n updateMessage: any,\n completion: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(\n CBSocketClient.responseMessageKey,\n updateMessage,\n message,\n YES,\n undefined,\n YES,\n nil,\n completion\n )\n \n }.bind(this)\n \n if (IS_SOCKET_ERROR(message.messageData)) {\n \n console.log(\"CBSocketClient did receive error message.\")\n \n console.log(message.messageData)\n \n \n }\n \n \n this._callbackHolder.socketDidReceiveMessageForKey(key, message, sendResponseFunction)\n \n }\n \n \n addTargetForMessagesForKeys(keys: string[], handlerFunction: CBSocketMessageHandlerFunction) {\n keys.forEach(function (this: CBSocketClient, key: string, index: number, array: string[]) {\n this.addTargetForMessagesForKey(key, handlerFunction)\n }.bind(this))\n }\n \n \n addTargetForMessagesForKey(key: string, handlerFunction: CBSocketMessageHandlerFunction) {\n \n this._callbackHolder.registerHandler(key, handlerFunction)\n \n if (IS_NOT(this._subscribedKeys[key])) {\n \n this._socket.on(key, function (this: CBSocketClient, message: CBSocketMessage<any>) {\n \n this.didReceiveMessageForKey(key, message)\n \n }.bind(this))\n \n this._subscribedKeys[key] = true\n \n }\n \n \n }\n \n addTargetForOneMessageForKey(key: string, handlerFunction: CBSocketMessageHandlerFunction) {\n \n this._callbackHolder.registerOnetimeHandler(key, handlerFunction)\n \n if (IS_NOT(this._subscribedKeys[key])) {\n \n this._socket.on(key, function (this: CBSocketClient, message: CBSocketMessage<any>) {\n \n this.didReceiveMessageForKey(key, message)\n \n }.bind(this))\n \n this._subscribedKeys[key] = true\n \n }\n \n \n }\n \n \n}\n\n\nexport const SocketClient: SocketClientInterface = new Proxy({ \"name\": \"SocketClient\" }, {\n \n get(target, key) {\n \n const result = (\n messageData: any,\n completionPolicy: string | undefined,\n isUserBound: boolean | undefined\n ) => CBCore.sharedInstance.socketClient.resultForMessageForKey(\n key as string,\n messageData,\n completionPolicy as any,\n isUserBound\n )\n \n \n return result\n \n }\n \n}) as any\n\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA0D;AAC1D,uBAAgG;AAChG,oBAAuB;
|
|
4
|
+
"sourcesContent": ["import { io, ManagerOptions, Socket, SocketOptions } from \"socket.io-client\"\nimport { FIRST_OR_NIL, IF, IS, IS_NIL, IS_NOT, MAKE_ID, nil, NO, RETURNER, UIObject, YES } from \"../../uicore-ts\"\nimport { CBCore } from \"./CBCore\"\nimport {\n CBSocketHandshakeInitMessage,\n CBSocketHandshakeResponseMessage,\n CBSocketKeepalivePayload,\n CBSocketMessage,\n CBSocketMessageCompletionFunction,\n CBSocketMessageHandlerFunction,\n CBSocketMessageSendResponseFunction,\n CBSocketMultipleMessage,\n CBSocketMultipleMessagecompletionFunction,\n CBSocketMultipleMessageObject,\n SocketClientInterface\n} from \"./CBDataInterfaces\"\nimport { CBSocketCallbackHolder } from \"./CBSocketCallbackHolder\"\n\n\ndeclare interface CBSocketClientMessageToBeSent {\n \n key: string;\n message: any;\n \n inResponseToMessage: CBSocketMessage<any>;\n keepWaitingForResponses: boolean;\n \n isBoundToUserWithID: string;\n \n completionPolicy: string;\n \n didSendFunction?: () => void;\n \n completion: CBSocketMessageCompletionFunction;\n \n}\n\n\ndeclare interface CBSocketClientErrorMessage {\n \n _isCBSocketErrorMessage: boolean;\n \n messageData: any;\n \n}\n\n\ntype FilterConditionally<Source, Condition> = Pick<Source, { [K in keyof Source]: Source[K] extends Condition ? K : never }[keyof Source]>;\n\n\nexport function IS_SOCKET_ERROR(object: any): object is CBSocketClientErrorMessage {\n \n const result = (IS(object) && object._isCBSocketErrorMessage)\n \n return result\n \n}\n\nexport function IS_NOT_SOCKET_ERROR(object: any) {\n \n return !IS_SOCKET_ERROR(object)\n \n}\n\n\n/**\n * A Promise returned by resultForMessageForKey.\n * Exposes didReceiveKeepalive() for registering a keepalive callback\n * in the same fluent style as the rest of the API.\n */\nexport interface CBSocketRequestPromise<T> extends Promise<T> {\n /**\n * Register a handler to be called each time a keepalive frame arrives\n * for this request.\n *\n * @param handler Called with the payload sent by the server.\n * @param extendsDefaultHandler When true (default) the application-level\n * defaultKeepaliveHandler fires first, then\n * this handler. When false this handler fires\n * alone and the default is suppressed for this\n * request.\n */\n didReceiveKeepalive(\n handler: (payload: CBSocketKeepalivePayload) => void,\n extendsDefaultHandler?: boolean\n ): CBSocketRequestPromise<T>\n}\n\n\nexport class CBSocketClient extends UIObject {\n \n _socket: Socket\n _isConnectionEstablished = NO\n \n _collectMessagesToSendLater = NO\n \n _messagesToBeSent: CBSocketClientMessageToBeSent[] = []\n \n static _sharedInstance: CBSocketClient\n \n _core: CBCore\n \n _subscribedKeys: {\n [x: string]: boolean\n } = {}\n \n _callbackHolder = new CBSocketCallbackHolder(this)\n \n static responseMessageKey = \"CBSocketResponseMessage\"\n static multipleMessageKey = \"CBSocketMultipleMessage\"\n \n \n static disconnectionMessage: CBSocketClientErrorMessage = {\n \n _isCBSocketErrorMessage: YES,\n \n messageData: \"Server disconnected\"\n \n }\n \n \n static timeoutMessage: CBSocketClientErrorMessage = {\n \n _isCBSocketErrorMessage: YES,\n \n messageData: \"Request timed out\"\n \n }\n \n \n /**\n * How long (in milliseconds) to wait for a server response before treating\n * the request as failed. Set to 0 to disable timeouts entirely.\n * Default: 30 000 ms (30 seconds).\n *\n * Each keepalive frame from the server resets this window, so long-running\n * requests only time out if the server goes completely silent for this duration.\n */\n requestTimeoutMs: number = 30_000\n\n /**\n * Application-level keepalive handler. Called for every keepalive frame\n * received on any request, unless the per-call handler was registered with\n * extendsDefaultHandler = false.\n *\n * Configure once at application startup:\n * CBSocketClient.sharedInstance.defaultKeepaliveHandler = payload => { ... }\n */\n defaultKeepaliveHandler?: (payload: CBSocketKeepalivePayload) => void\n \n \n constructor(core: CBCore) {\n \n super()\n \n this._core = core\n this._socket = io()\n \n this.socket.on(\"connect\", () => {\n \n console.log(\"Socket.io connected to server. clientID = \", this.socket, \" socketID = \", this.socket)\n \n this.sendUnsentMessages()\n \n })\n \n \n this._callbackHolder = new CBSocketCallbackHolder(this, this._callbackHolder)\n \n this.socket.on(\n \"CBSocketWelcomeMessage\",\n (message: CBSocketMessage<{ userProfile?: Record<string, string> }>) => {\n \n core.userProfile = message.messageData.userProfile\n \n this._isConnectionEstablished = YES\n \n this.sendUnsentMessages()\n \n }\n )\n \n this.socket.on(\"disconnect\", () => {\n \n console.log(\"Socket.io disconnected from server. clientID = \", this.socket)\n \n this._isConnectionEstablished = NO\n this._callbackHolder.isValid = NO\n this._callbackHolder.triggerDisconnectHandlers()\n \n \n })\n \n \n this.socket.on(\"CBPerformReconnect\", (message?: string) => {\n \n console.log(\"Performing socket reconnection.\")\n \n core.reloadSocketConnection()\n if (message) {\n this._core.dialogViewShowerClass.alert(message)\n }\n \n \n })\n \n \n this._socket.on(\n CBSocketClient.responseMessageKey,\n (message: CBSocketMessage<any>) => {\n \n this.didReceiveMessageForKey(CBSocketClient.responseMessageKey, message)\n \n }\n )\n \n this._socket.on(\n CBSocketClient.multipleMessageKey,\n (message: CBSocketMessage<CBSocketMultipleMessageObject[]>) => {\n \n console.log(\"Received \" + message.messageData.length + \" messages.\")\n // @ts-ignore\n if (document.cbsocketclientlogmessages) {\n console.log(message.messageData)\n }\n this.didReceiveMessageForKey(CBSocketClient.multipleMessageKey, message)\n \n }\n )\n \n \n }\n \n \n get socket() {\n return this._socket\n }\n \n \n cancelUnsentMessages(messagesToCancel: CBSocketClientMessageToBeSent[]) {\n \n this._messagesToBeSent = this._messagesToBeSent.filter((\n messageObject: CBSocketClientMessageToBeSent,\n index: number,\n array: CBSocketClientMessageToBeSent[]\n ) => !messagesToCancel.contains(messageObject))\n \n }\n \n \n sendUnsentMessages(receiveResponsesTogether = NO, completion?: CBSocketMultipleMessagecompletionFunction) {\n \n if (!this._isConnectionEstablished || this._collectMessagesToSendLater) {\n \n return\n \n }\n \n const groupedMessages: CBSocketMultipleMessageObject<any>[] = []\n const didSendFunctions: (() => void)[] = []\n \n \n this._messagesToBeSent.copy().forEach((messageToBeSentObject: CBSocketClientMessageToBeSent) => {\n \n if (this._isConnectionEstablished) {\n \n var message = messageToBeSentObject.message\n if (IS_NOT(message)) {\n message = \"\"\n }\n \n const identifier = MAKE_ID()\n \n const completion = messageToBeSentObject.completion\n \n const messageObject: CBSocketMessage<any> = {\n \n messageData: message,\n identifier: identifier,\n keepWaitingForResponses: messageToBeSentObject.keepWaitingForResponses,\n inResponseToIdentifier: messageToBeSentObject.inResponseToMessage.identifier,\n completionPolicy: messageToBeSentObject.completionPolicy\n \n }\n \n const shouldSendMessage = this._callbackHolder.socketShouldSendMessage(\n messageToBeSentObject.key,\n messageObject,\n messageToBeSentObject.completionPolicy,\n completion\n )\n \n if (shouldSendMessage) {\n \n groupedMessages.push({\n \n key: messageToBeSentObject.key,\n message: messageObject\n \n })\n \n }\n \n didSendFunctions.push(messageToBeSentObject.didSendFunction!)\n \n }\n \n })\n \n \n this._messagesToBeSent = []\n \n if (IS_NOT(groupedMessages.length)) {\n \n return\n \n }\n \n if (groupedMessages.length == 1) {\n \n console.log(\"sending 1 unsent message.\")\n \n }\n else {\n \n console.log(\"Sending \" + groupedMessages.length + \" unsent messages.\")\n \n }\n \n \n const messageObject: CBSocketMultipleMessage = {\n \n messageData: groupedMessages,\n identifier: MAKE_ID(),\n completionPolicy: CBSocketClient.completionPolicy.all,\n \n shouldGroupResponses: receiveResponsesTogether\n \n }\n \n //if (receiveResponsesTogether) {\n \n this._callbackHolder.socketWillSendMultipleMessage(messageObject, completion)\n \n //}\n \n // @ts-ignore\n if (document.cbsocketclientlogmessages) {\n console.log(\n \"CB socket client is sending multiple messages. [\",\n groupedMessages.everyElement.key.UI_elementValues?.join(\", \"), \"] \",\n messageObject\n )\n }\n \n this.socket.emit(CBSocketClient.multipleMessageKey, messageObject)\n \n \n didSendFunctions.forEach((didSendFunction, index, array) => {\n didSendFunction()\n })\n \n }\n \n \n static completionPolicy = {\n \n \"all\": \"all\",\n \"allDifferent\": \"allDifferent\",\n \"first\": \"first\",\n \"last\": \"last\",\n \"firstAndLast\": \"firstAndLast\",\n \"firstAndLastIfDifferent\": \"firstAndLastIfDifferent\",\n \"directOnly\": \"directOnly\",\n \"firstOnly\": \"firstOnly\",\n \"storedOrFirst\": \"storedOrFirst\"\n \n } as const\n \n \n sendUserBoundMessageForKeyWithPolicy(\n key: keyof SocketClientInterface,\n message: any,\n completionPolicy: keyof typeof CBSocketClient.completionPolicy,\n completion?: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(key as string, message, undefined, NO, completionPolicy, YES, nil, completion)\n \n }\n \n sendUserBoundMessageForKey(\n key: keyof SocketClientInterface,\n message: any,\n completion?: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(key as string, message, undefined, NO, undefined, YES, nil, completion)\n \n }\n \n sendMessageForKeyWithPolicy(\n key: keyof SocketClientInterface,\n message: any,\n completionPolicy: keyof typeof CBSocketClient.completionPolicy,\n completion?: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(key as string, message, undefined, NO, completionPolicy, NO, nil, completion)\n \n }\n \n sendMessageForKey(key: keyof SocketClientInterface, message: any, completion?: CBSocketMessageCompletionFunction) {\n \n this._sendMessageForKey(key as string, message, undefined, NO, undefined, NO, nil, completion)\n \n }\n \n \n resultForMessageForKey(\n key: keyof SocketClientInterface,\n message: any,\n completionPolicy?: keyof typeof CBSocketClient.completionPolicy,\n isUserBound = NO\n ): CBSocketRequestPromise<{\n responseMessage: any,\n result: any,\n errorResult: any,\n respondWithMessage: CBSocketMessageSendResponseFunction\n }> {\n\n // The identifier is assigned synchronously inside _sendMessageForKey.\n // We capture it via didObtainIdentifier so we can look up the descriptor\n // immediately after the send, before any async gap.\n let capturedIdentifier: string | undefined\n\n const basePromise = new Promise<{\n responseMessage: any,\n result: any,\n errorResult: any,\n respondWithMessage: CBSocketMessageSendResponseFunction\n }>((resolve, reject) => {\n\n this._sendMessageForKey(\n key as string,\n message,\n undefined,\n NO,\n completionPolicy,\n isUserBound,\n nil,\n (responseMessage, respondWithMessage) => resolve({\n\n responseMessage: responseMessage,\n result: IF(IS_NOT_SOCKET_ERROR(responseMessage))(() => responseMessage).ELSE(RETURNER(undefined)),\n errorResult: IF(IS_SOCKET_ERROR(responseMessage))(() => responseMessage).ELSE(RETURNER(undefined)),\n\n respondWithMessage: respondWithMessage\n\n }),\n (identifier) => { capturedIdentifier = identifier }\n )\n\n })\n\n const requestPromise = basePromise as CBSocketRequestPromise<any>\n\n requestPromise.didReceiveKeepalive = (\n handler: (payload: CBSocketKeepalivePayload) => void,\n extendsDefaultHandler = YES\n ): CBSocketRequestPromise<any> => {\n\n // The descriptor is pushed synchronously before _sendMessageForKey returns,\n // so capturedIdentifier is already set at this point.\n if (capturedIdentifier) {\n this._attachKeepaliveHandlerForIdentifier(capturedIdentifier, handler, extendsDefaultHandler)\n }\n\n return requestPromise\n\n }\n\n return requestPromise\n\n }\n\n\n /**\n * Finds the descriptor for the given request identifier and attaches the\n * keepalive handler fields to it.\n */\n _attachKeepaliveHandlerForIdentifier(\n identifier: string,\n handler: (payload: CBSocketKeepalivePayload) => void,\n extendsDefaultHandler: boolean\n ) {\n\n const descriptorKey = this._callbackHolder.keysForIdentifiers[identifier]\n if (!descriptorKey) {\n return\n }\n\n const descriptors = this._callbackHolder.messageDescriptors[descriptorKey]\n if (!descriptors) {\n return\n }\n\n const descriptor = descriptors.find(d => d.message.identifier === identifier)\n if (!descriptor) {\n return\n }\n\n descriptor.keepaliveHandler = handler\n descriptor.keepaliveHandlerOverridesDefault = !extendsDefaultHandler\n\n }\n\n \n _sendMessageForKey(\n key: string,\n message: any,\n inResponseToMessage: CBSocketMessage<any> = {} as any,\n keepMessageConnectionOpen = NO,\n completionPolicy: keyof typeof CBSocketClient.completionPolicy = CBSocketClient.completionPolicy.directOnly,\n isUserBound = NO,\n didSendFunction: () => void = nil,\n completion: CBSocketMessageCompletionFunction = nil,\n didObtainIdentifier?: (identifier: string) => void\n ) {\n \n if (IS_NIL(message)) {\n \n message = \"\"\n \n }\n \n if (this._isConnectionEstablished && !this._collectMessagesToSendLater) {\n \n const identifier = MAKE_ID()\n\n didObtainIdentifier?.(identifier)\n \n const messageObject: CBSocketMessage<any> = {\n \n messageData: message,\n identifier: identifier,\n keepWaitingForResponses: keepMessageConnectionOpen,\n inResponseToIdentifier: inResponseToMessage.identifier,\n completionPolicy: completionPolicy\n \n }\n \n const shouldSendMessage = this._callbackHolder.socketShouldSendMessage(\n key,\n messageObject,\n completionPolicy,\n completion\n )\n \n if (shouldSendMessage) {\n \n // @ts-ignore\n if (document.cbsocketclientlogmessages) {\n console.log(\n \"CB socket client is sending message. [\", key, \"] \",\n messageObject\n )\n }\n \n this.socket.emit(key, messageObject)\n \n }\n \n didSendFunction()\n \n }\n else {\n \n this._messagesToBeSent.push({\n \n key: key,\n message: message,\n inResponseToMessage: inResponseToMessage,\n keepWaitingForResponses: keepMessageConnectionOpen,\n completionPolicy: completionPolicy,\n isBoundToUserWithID: IF(isUserBound)(RETURNER(FIRST_OR_NIL(CBCore.sharedInstance.userProfile?._id)))(),\n didSendFunction: didSendFunction,\n completion: completion\n \n })\n \n return this._messagesToBeSent.lastElement\n \n }\n \n }\n \n \n sendMessagesAsGroup<FunctionReturnType extends object>(functionToCall: () => FunctionReturnType) {\n \n const collectMessagesToSendLater = this._collectMessagesToSendLater\n \n this._collectMessagesToSendLater = YES\n \n var result = functionToCall()\n \n this._collectMessagesToSendLater = collectMessagesToSendLater\n \n this.sendUnsentMessages()\n \n return result\n \n }\n \n sendAndReceiveMessagesAsGroup<FunctionReturnType extends object>(\n functionToCall: () => FunctionReturnType,\n completion?: CBSocketMultipleMessagecompletionFunction\n ) {\n \n const collectMessagesToSendLater = this._collectMessagesToSendLater\n \n this._collectMessagesToSendLater = YES\n \n var result = functionToCall()\n \n this._collectMessagesToSendLater = collectMessagesToSendLater\n \n this.sendUnsentMessages(YES, completion)\n \n return result\n \n }\n \n \n didReceiveMessageForKey(key: string, message: CBSocketMessage<any>) {\n \n \n const sendResponseFunction: CBSocketMessageSendResponseFunction = function (\n this: CBSocketClient,\n responseMessage: any,\n completion: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(\n CBSocketClient.responseMessageKey,\n responseMessage,\n message,\n NO,\n undefined,\n NO,\n nil,\n completion\n )\n \n }.bind(this) as any\n \n sendResponseFunction.sendIntermediateResponse = function (\n this: CBSocketClient,\n updateMessage: any,\n completion: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(\n CBSocketClient.responseMessageKey,\n updateMessage,\n message,\n YES,\n undefined,\n NO,\n nil,\n completion\n )\n \n }.bind(this)\n \n const sendUserBoundResponseFunction: CBSocketMessageSendResponseFunction = function (\n this: CBSocketClient,\n responseMessage: any,\n completion: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(\n CBSocketClient.responseMessageKey,\n responseMessage,\n message,\n NO,\n undefined,\n YES,\n nil,\n completion\n )\n \n }.bind(this) as any\n \n sendUserBoundResponseFunction.sendIntermediateResponse = function (\n this: CBSocketClient,\n updateMessage: any,\n completion: CBSocketMessageCompletionFunction\n ) {\n \n this._sendMessageForKey(\n CBSocketClient.responseMessageKey,\n updateMessage,\n message,\n YES,\n undefined,\n YES,\n nil,\n completion\n )\n \n }.bind(this)\n \n if (IS_SOCKET_ERROR(message.messageData)) {\n \n console.log(\"CBSocketClient did receive error message.\")\n \n console.log(message.messageData)\n \n \n }\n \n \n this._callbackHolder.socketDidReceiveMessageForKey(key, message, sendResponseFunction)\n \n }\n \n \n addTargetForMessagesForKeys(keys: string[], handlerFunction: CBSocketMessageHandlerFunction) {\n keys.forEach(function (this: CBSocketClient, key: string, index: number, array: string[]) {\n this.addTargetForMessagesForKey(key, handlerFunction)\n }.bind(this))\n }\n \n \n addTargetForMessagesForKey(key: string, handlerFunction: CBSocketMessageHandlerFunction) {\n \n this._callbackHolder.registerHandler(key, handlerFunction)\n \n if (IS_NOT(this._subscribedKeys[key])) {\n \n this._socket.on(key, function (this: CBSocketClient, message: CBSocketMessage<any>) {\n \n this.didReceiveMessageForKey(key, message)\n \n }.bind(this))\n \n this._subscribedKeys[key] = true\n \n }\n \n \n }\n \n addTargetForOneMessageForKey(key: string, handlerFunction: CBSocketMessageHandlerFunction) {\n \n this._callbackHolder.registerOnetimeHandler(key, handlerFunction)\n \n if (IS_NOT(this._subscribedKeys[key])) {\n \n this._socket.on(key, function (this: CBSocketClient, message: CBSocketMessage<any>) {\n \n this.didReceiveMessageForKey(key, message)\n \n }.bind(this))\n \n this._subscribedKeys[key] = true\n \n }\n \n \n }\n \n \n}\n\n\nexport const SocketClient: SocketClientInterface = new Proxy({ \"name\": \"SocketClient\" }, {\n \n get(target, key) {\n \n const result = (\n messageData: any,\n completionPolicy: string | undefined,\n isUserBound: boolean | undefined\n ) => CBCore.sharedInstance.socketClient.resultForMessageForKey(\n key as string,\n messageData,\n completionPolicy as any,\n isUserBound\n )\n \n \n return result\n \n }\n \n}) as any\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["completion", "messageObject"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
3
|
export type CBReferenceID = string;
|
|
7
4
|
|
|
8
5
|
|
|
@@ -22,9 +19,6 @@ export interface LanguagesData {
|
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
22
|
export interface CBFinancialAmount {
|
|
29
23
|
|
|
30
24
|
amount: number;
|
|
@@ -66,11 +60,6 @@ export interface CBDropdownDataItem<T> {
|
|
|
66
60
|
}
|
|
67
61
|
|
|
68
62
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
63
|
export interface CBFileAccessor {
|
|
75
64
|
|
|
76
65
|
fileData: CBFileData;
|
|
@@ -159,7 +148,7 @@ export interface CBSubscription {
|
|
|
159
148
|
|
|
160
149
|
isIndefinite: boolean;
|
|
161
150
|
|
|
162
|
-
subscriptionKind: number
|
|
151
|
+
subscriptionKind: number;
|
|
163
152
|
createdAt: Date;
|
|
164
153
|
updatedAt: Date;
|
|
165
154
|
|
|
@@ -201,9 +190,6 @@ export type SocketClientNoMessageFunction<ResultType> = (
|
|
|
201
190
|
) => Promise<SocketClientResult<ResultType>>;
|
|
202
191
|
|
|
203
192
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
193
|
export interface CBSocketMultipleMessageObject<MessageDataType = any> {
|
|
208
194
|
|
|
209
195
|
key: string;
|
|
@@ -212,6 +198,21 @@ export interface CBSocketMultipleMessageObject<MessageDataType = any> {
|
|
|
212
198
|
}
|
|
213
199
|
|
|
214
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Payload delivered to keepalive handlers on the client.
|
|
203
|
+
* All fields are optional — a bare keepalive with no payload is valid and
|
|
204
|
+
* simply resets the client's timeout window.
|
|
205
|
+
*/
|
|
206
|
+
export interface CBSocketKeepalivePayload {
|
|
207
|
+
/** Human-readable status message, e.g. "Processing items". */
|
|
208
|
+
message?: string
|
|
209
|
+
/** Completion estimate, 0-100. */
|
|
210
|
+
percentComplete?: number
|
|
211
|
+
/** Any additional fields the handler author may need. */
|
|
212
|
+
[key: string]: any
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
|
|
215
216
|
// CBSocket communication messages
|
|
216
217
|
export interface CBSocketMessage<MessageDataType = any> {
|
|
217
218
|
|
|
@@ -237,6 +238,13 @@ export interface CBSocketMessage<MessageDataType = any> {
|
|
|
237
238
|
// This tells the client that the response is valid for at least this long in ms
|
|
238
239
|
responseValidityDuration?: number;
|
|
239
240
|
|
|
241
|
+
/**
|
|
242
|
+
* When true this frame is a keepalive pulse, not a real response.
|
|
243
|
+
* The client resets its timeout and fires keepalive handlers; the normal
|
|
244
|
+
* completion machinery is bypassed entirely.
|
|
245
|
+
*/
|
|
246
|
+
isKeepalive?: boolean;
|
|
247
|
+
|
|
240
248
|
}
|
|
241
249
|
|
|
242
250
|
|
|
@@ -256,6 +264,7 @@ export type CBSocketMessageCompletionFunction = (
|
|
|
256
264
|
responseMessage: any,
|
|
257
265
|
respondWithMessage: CBSocketMessageSendResponseFunction
|
|
258
266
|
) => void;
|
|
267
|
+
|
|
259
268
|
export type CBSocketMessageHandlerFunction<ResponseMessageType = any> = (
|
|
260
269
|
message: any,
|
|
261
270
|
respondWithMessage: CBSocketMessageSendResponseFunction<ResponseMessageType>
|
|
@@ -282,6 +291,17 @@ export interface CBSocketMessageSendResponseFunction<ResponseMessageType = any>
|
|
|
282
291
|
|
|
283
292
|
sendIntermediateResponse(updateMessage: any, completion?: CBSocketMessageCompletionFunction): void;
|
|
284
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Sends a keepalive frame to the client immediately and resets the
|
|
296
|
+
* server-side auto-keepalive interval timer.
|
|
297
|
+
* No-ops silently if the final response has already been sent.
|
|
298
|
+
*
|
|
299
|
+
* Call this at natural yield points (after each await) during long-running
|
|
300
|
+
* handlers to keep the client timeout window alive and optionally deliver
|
|
301
|
+
* progress information.
|
|
302
|
+
*/
|
|
303
|
+
sendKeepalive(payload?: CBSocketKeepalivePayload): void;
|
|
304
|
+
|
|
285
305
|
// This tells the client to use the stored response if responseHash matches and also enables storing of responses
|
|
286
306
|
// in the client in the first place. Returns true if the hash matched.
|
|
287
307
|
confirmStoredResponseHash(responseHash: string, completion?: CBSocketMessageCompletionFunction): boolean;
|
|
@@ -295,7 +315,6 @@ export interface CBSocketMessageSendResponseFunction<ResponseMessageType = any>
|
|
|
295
315
|
}
|
|
296
316
|
|
|
297
317
|
|
|
298
|
-
|
|
299
318
|
// Socket handshake messages
|
|
300
319
|
export interface CBSocketHandshakeInitMessage {
|
|
301
320
|
|
|
@@ -319,9 +338,6 @@ export interface CBSocketHandshakeResponseMessage {
|
|
|
319
338
|
}
|
|
320
339
|
|
|
321
340
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
341
|
export type TypeWithoutKey<Type, Key> = Pick<Type, Exclude<keyof Type, Key>>;
|
|
326
342
|
|
|
327
343
|
export type TypeWithoutID<Type> = TypeWithoutKey<Type, "_id">;
|
|
@@ -337,9 +353,3 @@ export type RecursivePartial<T> = {
|
|
|
337
353
|
T[P] extends object ? RecursivePartial<T[P]> :
|
|
338
354
|
T[P];
|
|
339
355
|
};
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import objectHash from "object-hash"
|
|
2
2
|
import { FIRST, IS, IS_NOT, nil, NO, UIObject, YES } from "../../uicore-ts"
|
|
3
3
|
import {
|
|
4
|
+
CBSocketKeepalivePayload,
|
|
4
5
|
CBSocketMessage,
|
|
5
6
|
CBSocketMessageCompletionFunction,
|
|
6
7
|
CBSocketMessageHandlerFunction, CBSocketMessageSendResponseFunction, CBSocketMultipleMessage,
|
|
@@ -18,7 +19,6 @@ interface CBSocketCallbackHolderMessageDescriptor {
|
|
|
18
19
|
keepWaitingForResponses?: boolean;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
|
|
22
22
|
sentAtTime: number;
|
|
23
23
|
|
|
24
24
|
//completionTriggered: boolean;
|
|
@@ -35,6 +35,18 @@ interface CBSocketCallbackHolderMessageDescriptor {
|
|
|
35
35
|
completionFunction: CBSocketMessageCompletionFunction;
|
|
36
36
|
|
|
37
37
|
_timeoutId?: ReturnType<typeof setTimeout>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Called when a keepalive frame arrives for this descriptor's request.
|
|
41
|
+
* Registered via CBSocketRequestPromise.didReceiveKeepalive().
|
|
42
|
+
*/
|
|
43
|
+
keepaliveHandler?: (payload: CBSocketKeepalivePayload) => void;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* When true the defaultKeepaliveHandler on CBSocketClient is NOT called
|
|
47
|
+
* for this descriptor — only keepaliveHandler fires.
|
|
48
|
+
*/
|
|
49
|
+
keepaliveHandlerOverridesDefault: boolean;
|
|
38
50
|
|
|
39
51
|
}
|
|
40
52
|
|
|
@@ -96,7 +108,6 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
96
108
|
|
|
97
109
|
super()
|
|
98
110
|
|
|
99
|
-
|
|
100
111
|
this._socketClient = socketClient
|
|
101
112
|
|
|
102
113
|
if (IS(previousCallbackHolder)) {
|
|
@@ -117,7 +128,7 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
117
128
|
if (!descriptor.mainResponseReceived) {
|
|
118
129
|
|
|
119
130
|
this._cancelTimeoutForDescriptor(descriptor)
|
|
120
|
-
descriptor
|
|
131
|
+
descriptor?.completionFunction?.(CBSocketClient.disconnectionMessage, nil)
|
|
121
132
|
|
|
122
133
|
}
|
|
123
134
|
|
|
@@ -128,7 +139,6 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
128
139
|
|
|
129
140
|
registerHandler(key: string, handlerFunction: CBSocketMessageHandlerFunction) {
|
|
130
141
|
|
|
131
|
-
|
|
132
142
|
if (!this.handlers[key]) {
|
|
133
143
|
|
|
134
144
|
this.handlers[key] = []
|
|
@@ -137,12 +147,10 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
137
147
|
|
|
138
148
|
this.handlers[key].push(handlerFunction)
|
|
139
149
|
|
|
140
|
-
|
|
141
150
|
}
|
|
142
151
|
|
|
143
152
|
registerOnetimeHandler(key: string, handlerFunction: CBSocketMessageHandlerFunction) {
|
|
144
153
|
|
|
145
|
-
|
|
146
154
|
if (!this.onetimeHandlers[key]) {
|
|
147
155
|
|
|
148
156
|
this.onetimeHandlers[key] = []
|
|
@@ -151,7 +159,6 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
151
159
|
|
|
152
160
|
this.onetimeHandlers[key].push(handlerFunction)
|
|
153
161
|
|
|
154
|
-
|
|
155
162
|
}
|
|
156
163
|
|
|
157
164
|
|
|
@@ -218,7 +225,20 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
218
225
|
}
|
|
219
226
|
|
|
220
227
|
}
|
|
221
|
-
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Resets the timeout for a descriptor by cancelling the current timer and
|
|
232
|
+
* scheduling a fresh one. Called whenever a keepalive frame arrives so the
|
|
233
|
+
* request gets a full new window to complete.
|
|
234
|
+
*/
|
|
235
|
+
_resetTimeoutForDescriptor(descriptor: CBSocketCallbackHolderMessageDescriptor) {
|
|
236
|
+
|
|
237
|
+
this._cancelTimeoutForDescriptor(descriptor)
|
|
238
|
+
this._scheduleTimeoutForDescriptor(descriptor)
|
|
239
|
+
|
|
240
|
+
}
|
|
241
|
+
|
|
222
242
|
|
|
223
243
|
get storedResponseHashesDictionary() {
|
|
224
244
|
|
|
@@ -240,7 +260,6 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
240
260
|
|
|
241
261
|
const result = FIRST(hashObject, {} as any)
|
|
242
262
|
|
|
243
|
-
|
|
244
263
|
return result
|
|
245
264
|
|
|
246
265
|
}
|
|
@@ -270,7 +289,6 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
270
289
|
responseDataHash: string
|
|
271
290
|
) {
|
|
272
291
|
|
|
273
|
-
|
|
274
292
|
if (!responseMessage.canBeStoredAsResponse ||
|
|
275
293
|
(IS_NOT(responseMessage.messageData) && IS_NOT(responseMessage.messageDataHash))) {
|
|
276
294
|
|
|
@@ -278,10 +296,8 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
278
296
|
|
|
279
297
|
}
|
|
280
298
|
|
|
281
|
-
|
|
282
299
|
const localStorageKey = this.keyForRequestKeyAndRequestDataHash(requestKey, requestDataHash)
|
|
283
300
|
|
|
284
|
-
|
|
285
301
|
var validityDate: number
|
|
286
302
|
|
|
287
303
|
if (responseMessage.responseValidityDuration) {
|
|
@@ -305,7 +321,6 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
305
321
|
|
|
306
322
|
})
|
|
307
323
|
|
|
308
|
-
|
|
309
324
|
this.saveStoredResponseHashesDictionary(storedResponseHashesDictionary)
|
|
310
325
|
|
|
311
326
|
}
|
|
@@ -321,7 +336,6 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
321
336
|
|
|
322
337
|
saveInLocalStorage(key: string, object: any) {
|
|
323
338
|
|
|
324
|
-
|
|
325
339
|
const stringToSave = JSON.stringify(object)
|
|
326
340
|
|
|
327
341
|
if (stringToSave != localStorage[key]) {
|
|
@@ -330,7 +344,6 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
330
344
|
|
|
331
345
|
}
|
|
332
346
|
|
|
333
|
-
|
|
334
347
|
}
|
|
335
348
|
|
|
336
349
|
|
|
@@ -341,19 +354,16 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
341
354
|
completionFunction: CBSocketMessageCompletionFunction
|
|
342
355
|
) {
|
|
343
356
|
|
|
344
|
-
|
|
345
357
|
var result = YES
|
|
346
358
|
|
|
347
359
|
var triggerStoredResponseImmediately = NO
|
|
348
360
|
|
|
349
|
-
|
|
350
361
|
const messageDataHash = objectHash(message.messageData || nil)
|
|
351
362
|
|
|
352
363
|
const descriptorKey = "socketMessageDescriptor_" + key + messageDataHash
|
|
353
364
|
|
|
354
365
|
this.messageDescriptors[descriptorKey] = (this.messageDescriptors[descriptorKey] || [])
|
|
355
366
|
|
|
356
|
-
|
|
357
367
|
const hashObject = this.storedResponseHashObjectForKey(key, messageDataHash)
|
|
358
368
|
message.storedResponseHash = hashObject.hash
|
|
359
369
|
|
|
@@ -440,15 +450,16 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
440
450
|
|
|
441
451
|
//completionTriggered: NO,
|
|
442
452
|
|
|
443
|
-
|
|
444
453
|
messageDataHash: messageDataHash,
|
|
445
454
|
|
|
446
455
|
mainResponseReceived: NO,
|
|
447
456
|
anyMainResponseReceived: NO,
|
|
448
457
|
|
|
449
|
-
|
|
450
458
|
completionPolicy: completionPolicy,
|
|
451
|
-
completionFunction: completionFunction
|
|
459
|
+
completionFunction: completionFunction,
|
|
460
|
+
|
|
461
|
+
keepaliveHandler: undefined,
|
|
462
|
+
keepaliveHandlerOverridesDefault: NO
|
|
452
463
|
|
|
453
464
|
})
|
|
454
465
|
|
|
@@ -497,20 +508,16 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
497
508
|
completionFunction: CBSocketMultipleMessagecompletionFunction = CBSocketCallbackHolder.defaultMultipleMessagecompletionFunction
|
|
498
509
|
) {
|
|
499
510
|
|
|
500
|
-
|
|
501
511
|
const key = CBSocketClient.multipleMessageKey
|
|
502
512
|
|
|
503
|
-
|
|
504
513
|
const messageDataHash = objectHash(messageToSend.messageData || nil)
|
|
505
514
|
|
|
506
515
|
const descriptorKey = "socketMessageDescriptor_" + key + messageDataHash
|
|
507
516
|
|
|
508
517
|
this.messageDescriptors[descriptorKey] = (this.messageDescriptors[descriptorKey] || [])
|
|
509
518
|
|
|
510
|
-
|
|
511
519
|
messageToSend.storedResponseHash = this.storedResponseHashObjectForKey(key, messageDataHash).hash
|
|
512
520
|
|
|
513
|
-
|
|
514
521
|
this.messageDescriptors[descriptorKey].push({
|
|
515
522
|
|
|
516
523
|
key: key,
|
|
@@ -526,13 +533,11 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
526
533
|
|
|
527
534
|
//completionTriggered: NO,
|
|
528
535
|
|
|
529
|
-
|
|
530
536
|
messageDataHash: messageDataHash,
|
|
531
537
|
|
|
532
538
|
mainResponseReceived: NO,
|
|
533
539
|
anyMainResponseReceived: NO,
|
|
534
540
|
|
|
535
|
-
|
|
536
541
|
completionPolicy: CBSocketClient.completionPolicy.directOnly,
|
|
537
542
|
completionFunction: function (
|
|
538
543
|
this: CBSocketCallbackHolder,
|
|
@@ -566,7 +571,10 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
566
571
|
}.bind(this)
|
|
567
572
|
)
|
|
568
573
|
|
|
569
|
-
}.bind(this)
|
|
574
|
+
}.bind(this),
|
|
575
|
+
|
|
576
|
+
keepaliveHandler: undefined,
|
|
577
|
+
keepaliveHandlerOverridesDefault: NO
|
|
570
578
|
|
|
571
579
|
})
|
|
572
580
|
|
|
@@ -582,7 +590,6 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
582
590
|
sendResponseFunction: CBSocketMessageSendResponseFunction
|
|
583
591
|
) {
|
|
584
592
|
|
|
585
|
-
|
|
586
593
|
if (!this.isValid) {
|
|
587
594
|
|
|
588
595
|
return
|
|
@@ -629,7 +636,40 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
629
636
|
// Find descriptors for the key of the message that is being responded to
|
|
630
637
|
const descriptorKey = this.keysForIdentifiers[message.inResponseToIdentifier]
|
|
631
638
|
const descriptorsForKey = (this.messageDescriptors[descriptorKey] || [])
|
|
632
|
-
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
// --- Keepalive fast path ---
|
|
642
|
+
// A keepalive frame must not flow through the normal completion machinery.
|
|
643
|
+
// Handle it here and return early so nothing else fires.
|
|
644
|
+
if (message.isKeepalive) {
|
|
645
|
+
|
|
646
|
+
const payload: CBSocketKeepalivePayload = message.messageData || {}
|
|
647
|
+
|
|
648
|
+
descriptorsForKey.forEach((descriptor) => {
|
|
649
|
+
|
|
650
|
+
if (descriptor.message.identifier !== message.inResponseToIdentifier) {
|
|
651
|
+
return
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// Reset the client-side timeout so the request gets a full new window
|
|
655
|
+
this._resetTimeoutForDescriptor(descriptor)
|
|
656
|
+
|
|
657
|
+
// Fire the default handler unless the per-call handler overrides it
|
|
658
|
+
if (!descriptor.keepaliveHandlerOverridesDefault) {
|
|
659
|
+
this._socketClient.defaultKeepaliveHandler?.(payload)
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// Fire the per-call handler if one was registered
|
|
663
|
+
descriptor.keepaliveHandler?.(payload)
|
|
664
|
+
|
|
665
|
+
})
|
|
666
|
+
|
|
667
|
+
return
|
|
668
|
+
|
|
669
|
+
}
|
|
670
|
+
// --- End keepalive fast path ---
|
|
671
|
+
|
|
672
|
+
|
|
633
673
|
// Find response data hash to check for differences
|
|
634
674
|
const responseDataHash = message.messageDataHash
|
|
635
675
|
|