cbcore-ts 1.1.6 → 1.1.10
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/CBCore.d.ts +1 -1
- package/compiledScripts/CBCore.js.map +1 -1
- package/compiledScripts/CBSocketCallbackHolder.d.ts +7 -0
- package/compiledScripts/CBSocketCallbackHolder.js +20 -1
- package/compiledScripts/CBSocketCallbackHolder.js.map +3 -3
- package/compiledScripts/CBSocketClient.d.ts +2 -1
- package/compiledScripts/CBSocketClient.js +7 -1
- package/compiledScripts/CBSocketClient.js.map +2 -2
- package/package.json +1 -1
- package/scripts/CBCore.ts +1 -1
- package/scripts/CBSocketCallbackHolder.ts +29 -1
- package/scripts/CBSocketClient.ts +39 -27
|
@@ -113,7 +113,7 @@ export declare class CBCore extends UIObject {
|
|
|
113
113
|
didLogOut(): void;
|
|
114
114
|
updateLinkTargets(): void;
|
|
115
115
|
get isUserLoggedIn(): boolean;
|
|
116
|
-
|
|
116
|
+
_userProfile: CBUserProfile;
|
|
117
117
|
get userProfile(): CBUserProfile;
|
|
118
118
|
set userProfile(userProfile: CBUserProfile);
|
|
119
119
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/CBCore.ts"],
|
|
4
|
-
"sourcesContent": ["import { ManagerOptions, SocketOptions } from \"socket.io-client\"\nimport { NO } from \"uicore-ts\"\nimport { FIRST, IS, IS_NOT, nil, UICore, UILink, UIObject, UIRoute, UIViewBroadcastEvent, YES } from \"../../uicore-ts\"\nimport { CBLocalizedTextObject, CBUserProfile } from \"./CBDataInterfaces\"\nimport { CBLanguageService } from \"./CBLanguageService\"\nimport { CBServerClient } from \"./CBServerClient\"\nimport { CBSocketClient } from \"./CBSocketClient\"\n\n\ndeclare interface CBDialogViewShower {\n \n alert(text: string, dismissCallback?: Function): void\n \n localizedAlert(textObject: CBLocalizedTextObject, dismissCallback?: Function): void\n \n showActionIndicatorDialog(message: string, dismissCallback?: Function): void\n \n hideActionIndicatorDialog(): void\n \n}\n\n\ndeclare const CBCoreInitializerObject: any\n\n\n/**\n * CBCore \u2014 Application session model and library entry point.\n *\n * CBCore is a general-purpose library class. It must not contain any\n * project-specific business logic. To extend it for a specific project,\n * subclass CBCore and register the subclass as the singleton before any\n * other code accesses `CBCore.sharedInstance`.\n *\n * ## Extension pattern\n *\n * 1. Subclass CBCore in your project:\n *\n * ```typescript\n * class MyAppCore extends CBCore {\n *\n * // Additional session-level state goes here.\n * mySessionData: MySessionData | undefined = undefined\n *\n * // Override didSetUserProfile to fetch session data before the\n * // userDidLogIn broadcast fires. Call super only after your data\n * // is ready so that every listener receives a fully populated core.\n * override async didSetUserProfile() {\n * if (IS(this.userProfile)) {\n * this.mySessionData = await fetchMySessionData()\n * }\n * else {\n * this.mySessionData = undefined\n * }\n * super.didSetUserProfile()\n * }\n *\n * // Expose a typed singleton so callers never need CBCore.sharedInstance.\n * static override get sharedInstance(): MyAppCore {\n * return CBCore.sharedInstance as MyAppCore\n * }\n *\n * }\n * ```\n *\n * 2. Register the subclass at app startup, before UICore is initialised:\n *\n * ```typescript\n * CBCore.setSharedInstance(new MyAppCore())\n * CBCore.initIfNeededWithViewCore(new UICore(...))\n * ```\n *\n * 3. From that point on, every call to `CBCore.sharedInstance` \u2014 including\n * calls made internally by the library \u2014 returns the MyAppCore instance.\n * Project code should call `MyAppCore.sharedInstance` for the typed version.\n */\nexport class CBCore extends UIObject {\n \n private static _sharedInstance: CBCore\n \n viewCores: UICore[] = []\n \n _isUserLoggedIn = NO\n _cachedMinimizedChatInquiryIDs: string[] = nil\n _socketClient: CBSocketClient = new CBSocketClient(this)\n _serverClient: CBServerClient = new CBServerClient(this)\n \n _functionsToCallForEachSocketClient: (() => void)[] = []\n \n _models: any[] = []\n \n dialogViewShowerClass: CBDialogViewShower = nil\n \n constructor() {\n \n super()\n \n if (CBCoreInitializerObject) {\n \n CBLanguageService.useStoredLanguageValues(CBCoreInitializerObject.languageValues)\n \n }\n \n \n window.addEventListener(\"storage\", function (this: CBCore, event: StorageEvent) {\n \n if (event.newValue == event.oldValue) {\n return\n }\n \n if (event.key == \"CBLanguageKey\") {\n this.didSetLanguageKey()\n }\n \n }.bind(this))\n \n \n this.didSetLanguageKey()\n \n \n }\n \n \n static initIfNeededWithViewCore(\n viewCore: UICore\n ) {\n CBCore.sharedInstance.viewCores.push(viewCore)\n }\n \n \n /**\n * Returns the shared singleton instance.\n *\n * If `setSharedInstance` was called before this getter was first accessed,\n * that instance is returned. Otherwise a default `CBCore` is created.\n * Library-internal code always goes through this getter, so registering a\n * subclass via `setSharedInstance` is sufficient to replace the singleton\n * for the entire session.\n */\n static get sharedInstance() {\n if (!CBCore._sharedInstance) {\n CBCore._sharedInstance = new CBCore()\n }\n return CBCore._sharedInstance\n }\n \n \n /**\n * Registers a subclass instance as the application singleton.\n *\n * Call this once at app startup, before `CBCore.sharedInstance` or\n * `CBCore.initIfNeededWithViewCore` are first accessed. Calling it after\n * the singleton has already been created has no effect and will throw in\n * development to catch accidental misuse.\n *\n * ```typescript\n * // App entry point \u2014 must be the very first thing that runs.\n * CBCore.setSharedInstance(new MyAppCore())\n * CBCore.initIfNeededWithViewCore(new UICore(\"root\", RootViewController))\n * ```\n */\n static setSharedInstance(instance: CBCore) {\n \n if (CBCore._sharedInstance) {\n /// #if DEV\n throw new Error(\n \"CBCore.setSharedInstance must be called before sharedInstance is first accessed. \" +\n \"Move the call to the very top of your app entry point.\"\n )\n /// #endif\n return\n }\n \n CBCore._sharedInstance = instance\n \n }\n \n \n static broadcastEventName = {\n \n \"userDidLogIn\": \"UserDidLogIn\",\n \"userDidLogOut\": \"UserDidLogOut\"\n \n } as const\n \n broadcastMessageInRootViewTree(message: UIViewBroadcastEvent) {\n \n this.viewCores.everyElement.rootViewController.view.broadcastEventInSubtree(message)\n \n }\n \n \n get socketClient() {\n return this._socketClient\n }\n \n get serverClient() {\n return this._serverClient\n }\n \n \n set isUserLoggedIn(isUserLoggedIn: boolean) {\n const previousValue = this.isUserLoggedIn\n this._isUserLoggedIn = isUserLoggedIn\n this.didSetIsUserLoggedIn(previousValue)\n }\n \n didSetIsUserLoggedIn(previousValue: boolean) {\n \n const isUserLoggedIn = this.isUserLoggedIn\n \n if (isUserLoggedIn && previousValue != isUserLoggedIn) {\n \n // Send message to views\n this.broadcastMessageInRootViewTree({\n name: CBCore.broadcastEventName.userDidLogIn,\n parameters: nil\n })\n \n this.updateLinkTargets()\n \n }\n else if (previousValue != isUserLoggedIn) {\n \n this.didLogOut()\n \n }\n \n }\n \n /**\n * Called when the user transitions from logged-in to logged-out.\n * The default implementation clears the route and broadcasts `userDidLogOut`.\n * Subclasses may override this to suppress the route change when they intend\n * to navigate somewhere specific immediately after logout.\n */\n didLogOut() {\n \n this.performFunctionWithDelay(0.01, function (this: CBCore) {\n \n UIRoute.currentRoute.routeByRemovingComponentsOtherThanOnesNamed([\n \"settings\"\n ]).apply()\n \n this.broadcastMessageInRootViewTree({\n name: CBCore.broadcastEventName.userDidLogOut,\n parameters: nil\n })\n \n this.updateLinkTargets()\n \n }.bind(this))\n \n }\n \n updateLinkTargets() {\n this.viewCores.everyElement.rootViewController.view.forEachViewInSubtree(function (view) {\n if (view instanceof UILink) {\n view.updateTarget()\n }\n })\n }\n \n get isUserLoggedIn() {\n return this._isUserLoggedIn\n }\n \n \n private _userProfile: CBUserProfile\n \n get userProfile() {\n return this._userProfile\n }\n \n set userProfile(userProfile: CBUserProfile) {\n this._userProfile = userProfile\n this.didSetUserProfile()\n }\n \n /**\n * Called whenever `userProfile` is assigned.\n *\n * The default implementation derives `isUserLoggedIn` from the profile\n * and triggers the login/logout broadcast via `didSetIsUserLoggedIn`.\n *\n * Subclasses may override this to fetch additional session data before\n * the broadcast fires. The override must be `async` and must call\n * `super.didSetUserProfile()` after it has finished populating any\n * extra state, so that all broadcast listeners receive a complete core:\n *\n * ```typescript\n * override async didSetUserProfile() {\n * if (IS(this.userProfile)) {\n * this.companyStatus = (await SocketClient.CurrentUserStatusInCompany()).result\n * }\n * else {\n * this.companyStatus = undefined\n * }\n * super.didSetUserProfile() // broadcast fires here\n * }\n * ```\n */\n didSetUserProfile() {\n this.isUserLoggedIn = IS(this.userProfile)\n }\n \n \n set languageKey(languageKey: string) {\n if (IS_NOT(languageKey)) {\n localStorage.removeItem(\"CBLanguageKey\")\n }\n localStorage.setItem(\"CBLanguageKey\", JSON.stringify(languageKey))\n this.didSetLanguageKey()\n }\n \n get languageKey() {\n return FIRST(localStorage.getItem(\"CBLanguageKey\"), CBLanguageService.defaultLanguageKey).replace(\n \"\\\"\",\n \"\"\n ).replace(\"\\\"\", \"\")\n }\n \n didSetLanguageKey() {\n UIRoute.currentRoute.routeWithComponent(\n \"settings\",\n { \"language\": this.languageKey },\n YES\n ).applyByReplacingCurrentRouteInHistory()\n }\n \n \n reloadSocketConnection() {\n \n // @ts-ignore\n this.socketClient.socket.disconnect()\n \n const messagesToBeSent = this.socketClient._messagesToBeSent.filter(function (messageItem, index, array) {\n \n return (!messageItem.isBoundToUserWithID || messageItem.isBoundToUserWithID ==\n CBCore.sharedInstance.userProfile?._id)\n \n })\n \n this._socketClient = new CBSocketClient(this)\n this._socketClient._messagesToBeSent = messagesToBeSent\n \n const socketClient = this._socketClient\n \n this._models.forEach(function (model, index, array) {\n \n model.setSocketClient(socketClient)\n \n })\n \n this._functionsToCallForEachSocketClient.forEach(function (functionToCall, index, array) {\n \n functionToCall()\n \n })\n \n \n }\n \n \n callFunctionForEachSocketClient(functionToCall: () => void) {\n this._functionsToCallForEachSocketClient.push(functionToCall)\n functionToCall()\n }\n \n \n}\n"],
|
|
4
|
+
"sourcesContent": ["import { ManagerOptions, SocketOptions } from \"socket.io-client\"\nimport { NO } from \"uicore-ts\"\nimport { FIRST, IS, IS_NOT, nil, UICore, UILink, UIObject, UIRoute, UIViewBroadcastEvent, YES } from \"../../uicore-ts\"\nimport { CBLocalizedTextObject, CBUserProfile } from \"./CBDataInterfaces\"\nimport { CBLanguageService } from \"./CBLanguageService\"\nimport { CBServerClient } from \"./CBServerClient\"\nimport { CBSocketClient } from \"./CBSocketClient\"\n\n\ndeclare interface CBDialogViewShower {\n \n alert(text: string, dismissCallback?: Function): void\n \n localizedAlert(textObject: CBLocalizedTextObject, dismissCallback?: Function): void\n \n showActionIndicatorDialog(message: string, dismissCallback?: Function): void\n \n hideActionIndicatorDialog(): void\n \n}\n\n\ndeclare const CBCoreInitializerObject: any\n\n\n/**\n * CBCore \u2014 Application session model and library entry point.\n *\n * CBCore is a general-purpose library class. It must not contain any\n * project-specific business logic. To extend it for a specific project,\n * subclass CBCore and register the subclass as the singleton before any\n * other code accesses `CBCore.sharedInstance`.\n *\n * ## Extension pattern\n *\n * 1. Subclass CBCore in your project:\n *\n * ```typescript\n * class MyAppCore extends CBCore {\n *\n * // Additional session-level state goes here.\n * mySessionData: MySessionData | undefined = undefined\n *\n * // Override didSetUserProfile to fetch session data before the\n * // userDidLogIn broadcast fires. Call super only after your data\n * // is ready so that every listener receives a fully populated core.\n * override async didSetUserProfile() {\n * if (IS(this.userProfile)) {\n * this.mySessionData = await fetchMySessionData()\n * }\n * else {\n * this.mySessionData = undefined\n * }\n * super.didSetUserProfile()\n * }\n *\n * // Expose a typed singleton so callers never need CBCore.sharedInstance.\n * static override get sharedInstance(): MyAppCore {\n * return CBCore.sharedInstance as MyAppCore\n * }\n *\n * }\n * ```\n *\n * 2. Register the subclass at app startup, before UICore is initialised:\n *\n * ```typescript\n * CBCore.setSharedInstance(new MyAppCore())\n * CBCore.initIfNeededWithViewCore(new UICore(...))\n * ```\n *\n * 3. From that point on, every call to `CBCore.sharedInstance` \u2014 including\n * calls made internally by the library \u2014 returns the MyAppCore instance.\n * Project code should call `MyAppCore.sharedInstance` for the typed version.\n */\nexport class CBCore extends UIObject {\n \n private static _sharedInstance: CBCore\n \n viewCores: UICore[] = []\n \n _isUserLoggedIn = NO\n _cachedMinimizedChatInquiryIDs: string[] = nil\n _socketClient: CBSocketClient = new CBSocketClient(this)\n _serverClient: CBServerClient = new CBServerClient(this)\n \n _functionsToCallForEachSocketClient: (() => void)[] = []\n \n _models: any[] = []\n \n dialogViewShowerClass: CBDialogViewShower = nil\n \n constructor() {\n \n super()\n \n if (CBCoreInitializerObject) {\n \n CBLanguageService.useStoredLanguageValues(CBCoreInitializerObject.languageValues)\n \n }\n \n \n window.addEventListener(\"storage\", function (this: CBCore, event: StorageEvent) {\n \n if (event.newValue == event.oldValue) {\n return\n }\n \n if (event.key == \"CBLanguageKey\") {\n this.didSetLanguageKey()\n }\n \n }.bind(this))\n \n \n this.didSetLanguageKey()\n \n \n }\n \n \n static initIfNeededWithViewCore(\n viewCore: UICore\n ) {\n CBCore.sharedInstance.viewCores.push(viewCore)\n }\n \n \n /**\n * Returns the shared singleton instance.\n *\n * If `setSharedInstance` was called before this getter was first accessed,\n * that instance is returned. Otherwise a default `CBCore` is created.\n * Library-internal code always goes through this getter, so registering a\n * subclass via `setSharedInstance` is sufficient to replace the singleton\n * for the entire session.\n */\n static get sharedInstance() {\n if (!CBCore._sharedInstance) {\n CBCore._sharedInstance = new CBCore()\n }\n return CBCore._sharedInstance\n }\n \n \n /**\n * Registers a subclass instance as the application singleton.\n *\n * Call this once at app startup, before `CBCore.sharedInstance` or\n * `CBCore.initIfNeededWithViewCore` are first accessed. Calling it after\n * the singleton has already been created has no effect and will throw in\n * development to catch accidental misuse.\n *\n * ```typescript\n * // App entry point \u2014 must be the very first thing that runs.\n * CBCore.setSharedInstance(new MyAppCore())\n * CBCore.initIfNeededWithViewCore(new UICore(\"root\", RootViewController))\n * ```\n */\n static setSharedInstance(instance: CBCore) {\n \n if (CBCore._sharedInstance) {\n /// #if DEV\n throw new Error(\n \"CBCore.setSharedInstance must be called before sharedInstance is first accessed. \" +\n \"Move the call to the very top of your app entry point.\"\n )\n /// #endif\n return\n }\n \n CBCore._sharedInstance = instance\n \n }\n \n \n static broadcastEventName = {\n \n \"userDidLogIn\": \"UserDidLogIn\",\n \"userDidLogOut\": \"UserDidLogOut\"\n \n } as const\n \n broadcastMessageInRootViewTree(message: UIViewBroadcastEvent) {\n \n this.viewCores.everyElement.rootViewController.view.broadcastEventInSubtree(message)\n \n }\n \n \n get socketClient() {\n return this._socketClient\n }\n \n get serverClient() {\n return this._serverClient\n }\n \n \n set isUserLoggedIn(isUserLoggedIn: boolean) {\n const previousValue = this.isUserLoggedIn\n this._isUserLoggedIn = isUserLoggedIn\n this.didSetIsUserLoggedIn(previousValue)\n }\n \n didSetIsUserLoggedIn(previousValue: boolean) {\n \n const isUserLoggedIn = this.isUserLoggedIn\n \n if (isUserLoggedIn && previousValue != isUserLoggedIn) {\n \n // Send message to views\n this.broadcastMessageInRootViewTree({\n name: CBCore.broadcastEventName.userDidLogIn,\n parameters: nil\n })\n \n this.updateLinkTargets()\n \n }\n else if (previousValue != isUserLoggedIn) {\n \n this.didLogOut()\n \n }\n \n }\n \n /**\n * Called when the user transitions from logged-in to logged-out.\n * The default implementation clears the route and broadcasts `userDidLogOut`.\n * Subclasses may override this to suppress the route change when they intend\n * to navigate somewhere specific immediately after logout.\n */\n didLogOut() {\n \n this.performFunctionWithDelay(0.01, function (this: CBCore) {\n \n UIRoute.currentRoute.routeByRemovingComponentsOtherThanOnesNamed([\n \"settings\"\n ]).apply()\n \n this.broadcastMessageInRootViewTree({\n name: CBCore.broadcastEventName.userDidLogOut,\n parameters: nil\n })\n \n this.updateLinkTargets()\n \n }.bind(this))\n \n }\n \n updateLinkTargets() {\n this.viewCores.everyElement.rootViewController.view.forEachViewInSubtree(function (view) {\n if (view instanceof UILink) {\n view.updateTarget()\n }\n })\n }\n \n get isUserLoggedIn() {\n return this._isUserLoggedIn\n }\n \n \n _userProfile: CBUserProfile\n \n get userProfile() {\n return this._userProfile\n }\n \n set userProfile(userProfile: CBUserProfile) {\n this._userProfile = userProfile\n this.didSetUserProfile()\n }\n \n /**\n * Called whenever `userProfile` is assigned.\n *\n * The default implementation derives `isUserLoggedIn` from the profile\n * and triggers the login/logout broadcast via `didSetIsUserLoggedIn`.\n *\n * Subclasses may override this to fetch additional session data before\n * the broadcast fires. The override must be `async` and must call\n * `super.didSetUserProfile()` after it has finished populating any\n * extra state, so that all broadcast listeners receive a complete core:\n *\n * ```typescript\n * override async didSetUserProfile() {\n * if (IS(this.userProfile)) {\n * this.companyStatus = (await SocketClient.CurrentUserStatusInCompany()).result\n * }\n * else {\n * this.companyStatus = undefined\n * }\n * super.didSetUserProfile() // broadcast fires here\n * }\n * ```\n */\n didSetUserProfile() {\n this.isUserLoggedIn = IS(this.userProfile)\n }\n \n \n set languageKey(languageKey: string) {\n if (IS_NOT(languageKey)) {\n localStorage.removeItem(\"CBLanguageKey\")\n }\n localStorage.setItem(\"CBLanguageKey\", JSON.stringify(languageKey))\n this.didSetLanguageKey()\n }\n \n get languageKey() {\n return FIRST(localStorage.getItem(\"CBLanguageKey\"), CBLanguageService.defaultLanguageKey).replace(\n \"\\\"\",\n \"\"\n ).replace(\"\\\"\", \"\")\n }\n \n didSetLanguageKey() {\n UIRoute.currentRoute.routeWithComponent(\n \"settings\",\n { \"language\": this.languageKey },\n YES\n ).applyByReplacingCurrentRouteInHistory()\n }\n \n \n reloadSocketConnection() {\n \n // @ts-ignore\n this.socketClient.socket.disconnect()\n \n const messagesToBeSent = this.socketClient._messagesToBeSent.filter(function (messageItem, index, array) {\n \n return (!messageItem.isBoundToUserWithID || messageItem.isBoundToUserWithID ==\n CBCore.sharedInstance.userProfile?._id)\n \n })\n \n this._socketClient = new CBSocketClient(this)\n this._socketClient._messagesToBeSent = messagesToBeSent\n \n const socketClient = this._socketClient\n \n this._models.forEach(function (model, index, array) {\n \n model.setSocketClient(socketClient)\n \n })\n \n this._functionsToCallForEachSocketClient.forEach(function (functionToCall, index, array) {\n \n functionToCall()\n \n })\n \n \n }\n \n \n callFunctionForEachSocketClient(functionToCall: () => void) {\n this._functionsToCallForEachSocketClient.push(functionToCall)\n functionToCall()\n }\n \n \n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["import_uicore_ts"]
|
|
7
7
|
}
|
|
@@ -64,6 +64,13 @@ export declare class CBSocketCallbackHolder extends UIObject {
|
|
|
64
64
|
* request gets a full new window to complete.
|
|
65
65
|
*/
|
|
66
66
|
_resetTimeoutForDescriptor(descriptor: CBSocketCallbackHolderMessageDescriptor): void;
|
|
67
|
+
/**
|
|
68
|
+
* Starts the timeout for the descriptor associated with the given identifier.
|
|
69
|
+
* Called by CBSocketClient immediately after socket.emit() so the timer only
|
|
70
|
+
* runs while the server is actually reachable. If the server disconnects before
|
|
71
|
+
* responding, triggerDisconnectHandlers() covers cleanup without needing a timer.
|
|
72
|
+
*/
|
|
73
|
+
scheduleTimeoutForIdentifierIfNeeded(identifier: string): void;
|
|
67
74
|
get storedResponseHashesDictionary(): {
|
|
68
75
|
[x: string]: {
|
|
69
76
|
hash: string;
|
|
@@ -117,6 +117,26 @@ class CBSocketCallbackHolder extends import_uicore_ts.UIObject {
|
|
|
117
117
|
this._cancelTimeoutForDescriptor(descriptor);
|
|
118
118
|
this._scheduleTimeoutForDescriptor(descriptor);
|
|
119
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Starts the timeout for the descriptor associated with the given identifier.
|
|
122
|
+
* Called by CBSocketClient immediately after socket.emit() so the timer only
|
|
123
|
+
* runs while the server is actually reachable. If the server disconnects before
|
|
124
|
+
* responding, triggerDisconnectHandlers() covers cleanup without needing a timer.
|
|
125
|
+
*/
|
|
126
|
+
scheduleTimeoutForIdentifierIfNeeded(identifier) {
|
|
127
|
+
const descriptorKey = this.keysForIdentifiers[identifier];
|
|
128
|
+
if (!descriptorKey) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const descriptors = this.messageDescriptors[descriptorKey];
|
|
132
|
+
if (!descriptors) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const descriptor = descriptors.find((descriptor2) => descriptor2.message.identifier === identifier);
|
|
136
|
+
if (descriptor) {
|
|
137
|
+
this._scheduleTimeoutForDescriptor(descriptor);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
120
140
|
get storedResponseHashesDictionary() {
|
|
121
141
|
if ((0, import_uicore_ts.IS_NOT)(this._storedResponseHashesDictionary)) {
|
|
122
142
|
this._storedResponseHashesDictionary = JSON.parse(localStorage["CBSocketResponseHashesDictionary"] || "{}");
|
|
@@ -227,7 +247,6 @@ class CBSocketCallbackHolder extends import_uicore_ts.UIObject {
|
|
|
227
247
|
keepaliveHandlerOverridesDefault: import_uicore_ts.NO
|
|
228
248
|
});
|
|
229
249
|
const pushedDescriptor = this.messageDescriptors[descriptorKey].lastElement;
|
|
230
|
-
this._scheduleTimeoutForDescriptor(pushedDescriptor);
|
|
231
250
|
this.keysForIdentifiers[message.identifier] = descriptorKey;
|
|
232
251
|
}
|
|
233
252
|
if (triggerStoredResponseImmediately) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/CBSocketCallbackHolder.ts"],
|
|
4
|
-
"sourcesContent": ["import objectHash from \"object-hash\"\nimport { FIRST, IS, IS_NOT, nil, NO, UIObject, YES } from \"../../uicore-ts\"\nimport {\n CBSocketKeepalivePayload,\n CBSocketMessage,\n CBSocketMessageCompletionFunction,\n CBSocketMessageHandlerFunction, CBSocketMessageSendResponseFunction, CBSocketMultipleMessage,\n CBSocketMultipleMessagecompletionFunction, CBSocketMultipleMessageObject\n} from \"./CBDataInterfaces\"\nimport { CBSocketClient } from \"./CBSocketClient\"\n\n\ninterface CBSocketCallbackHolderMessageDescriptor {\n \n key: string;\n message: {\n identifier: string;\n inResponseToIdentifier?: string;\n keepWaitingForResponses?: boolean;\n }\n \n sentAtTime: number;\n \n //completionTriggered: boolean;\n \n messageDataHash: string;\n \n responseDataHash?: string;\n \n mainResponseReceived: boolean;\n \n anyMainResponseReceived: boolean;\n \n completionPolicy: string;\n completionFunction: CBSocketMessageCompletionFunction;\n \n _timeoutId?: ReturnType<typeof setTimeout>;\n \n /**\n * Called when a keepalive frame arrives for this descriptor's request.\n * Registered via CBSocketRequestPromise.didReceiveKeepalive().\n */\n keepaliveHandler?: (payload: CBSocketKeepalivePayload) => void;\n \n /**\n * When true the defaultKeepaliveHandler on CBSocketClient is NOT called\n * for this descriptor \u2014 only keepaliveHandler fires.\n */\n keepaliveHandlerOverridesDefault: boolean;\n \n}\n\n\ninterface CBSocketCallbackHolderStoredResponseObject {\n \n messageKey: string;\n messageData: any;\n messageDataHash: string;\n \n}\n\n\nexport class CBSocketCallbackHolder extends UIObject {\n \n messageDescriptors: {\n \n [x: string]: CBSocketCallbackHolderMessageDescriptor[]\n \n } = {}\n \n handlers: {\n [x: string]: CBSocketMessageHandlerFunction[]\n } = {}\n \n onetimeHandlers: {\n [x: string]: CBSocketMessageHandlerFunction[]\n } = {}\n \n keysForIdentifiers: {\n \n [x: string]: string\n \n } = {}\n \n \n isValid = YES\n _storeableResponseKeys: string[] = []\n _storedResponseHashesDictionary: {\n \n [x: string]: {\n \n hash: string,\n validityDate: number\n \n }\n \n } = {}\n _verifiedResponseHashesDictionary: {\n \n [x: string]: boolean\n \n } = {}\n \n _socketClient: CBSocketClient\n \n \n constructor(socketClient: CBSocketClient, previousCallbackHolder?: CBSocketCallbackHolder) {\n \n super()\n \n this._socketClient = socketClient\n \n if (IS(previousCallbackHolder)) {\n \n this.handlers = previousCallbackHolder.handlers\n this._verifiedResponseHashesDictionary = previousCallbackHolder._verifiedResponseHashesDictionary\n \n }\n \n \n }\n \n \n triggerDisconnectHandlers() {\n \n this.messageDescriptors.forEach(\n function (this: CBSocketCallbackHolder, descriptor: CBSocketCallbackHolderMessageDescriptor, key: string) {\n \n if (!descriptor.mainResponseReceived) {\n \n this._cancelTimeoutForDescriptor(descriptor)\n \n if (typeof descriptor?.completionFunction == \"function\") {\n descriptor.completionFunction(CBSocketClient.disconnectionMessage, nil)\n }\n \n }\n \n }.bind(this))\n \n }\n \n \n registerHandler(key: string, handlerFunction: CBSocketMessageHandlerFunction) {\n \n if (!this.handlers[key]) {\n \n this.handlers[key] = []\n \n }\n \n this.handlers[key].push(handlerFunction)\n \n }\n \n registerOnetimeHandler(key: string, handlerFunction: CBSocketMessageHandlerFunction) {\n \n if (!this.onetimeHandlers[key]) {\n \n this.onetimeHandlers[key] = []\n \n }\n \n this.onetimeHandlers[key].push(handlerFunction)\n \n }\n \n \n _scheduleTimeoutForDescriptor(descriptor: CBSocketCallbackHolderMessageDescriptor) {\n \n const timeoutMs = this._socketClient.requestTimeoutMs\n \n if (!timeoutMs) {\n \n return\n \n }\n \n descriptor._timeoutId = setTimeout(() => {\n \n if (descriptor.mainResponseReceived) {\n \n return\n \n }\n \n console.warn(\n `CBSocketCallbackHolder: request \"${descriptor.key}\" timed out after ${timeoutMs} ms`\n )\n \n descriptor.mainResponseReceived = YES\n \n descriptor.completionFunction(CBSocketClient.timeoutMessage, nil)\n \n const descriptorKey = this.keysForIdentifiers[descriptor.message.identifier]\n \n if (descriptorKey) {\n \n const descriptorsForKey = this.messageDescriptors[descriptorKey]\n \n if (descriptorsForKey) {\n \n descriptorsForKey.removeElement(descriptor)\n \n if (descriptorsForKey.length === 0) {\n \n delete this.messageDescriptors[descriptorKey]\n \n }\n \n }\n \n delete this.keysForIdentifiers[descriptor.message.identifier]\n \n }\n \n }, timeoutMs)\n \n }\n \n \n _cancelTimeoutForDescriptor(descriptor: CBSocketCallbackHolderMessageDescriptor) {\n \n if (descriptor._timeoutId !== undefined) {\n \n clearTimeout(descriptor._timeoutId)\n descriptor._timeoutId = undefined\n \n }\n \n }\n \n \n /**\n * Resets the timeout for a descriptor by cancelling the current timer and\n * scheduling a fresh one. Called whenever a keepalive frame arrives so the\n * request gets a full new window to complete.\n */\n _resetTimeoutForDescriptor(descriptor: CBSocketCallbackHolderMessageDescriptor) {\n \n this._cancelTimeoutForDescriptor(descriptor)\n this._scheduleTimeoutForDescriptor(descriptor)\n \n }\n \n \n get storedResponseHashesDictionary() {\n \n if (IS_NOT(this._storedResponseHashesDictionary)) {\n \n this._storedResponseHashesDictionary = JSON.parse(localStorage[\"CBSocketResponseHashesDictionary\"] || \"{}\")\n \n }\n \n return this._storedResponseHashesDictionary\n \n }\n \n storedResponseHashObjectForKey(requestKey: string, requestDataHash: string) {\n \n const localStorageKey = this.keyForRequestKeyAndRequestDataHash(requestKey, requestDataHash)\n \n const hashObject = this.storedResponseHashesDictionary[localStorageKey]\n \n const result = FIRST(hashObject, {} as any)\n \n return result\n \n }\n \n storedResponseForKey(requestKey: string, requestDataHash: string) {\n \n const localStorageKey = this.keyForRequestKeyAndRequestDataHash(requestKey, requestDataHash)\n \n const storedObject = JSON.parse(localStorage[localStorageKey] || \"{}\")\n \n return storedObject.responseMessageData\n \n }\n \n keyForRequestKeyAndRequestDataHash(requestKey: string, requestDataHash: string) {\n \n const result = \"_CBSCH_LS_key_\" + requestKey + \"_\" + requestDataHash\n \n return result\n \n }\n \n storeResponse(\n requestKey: string,\n requestDataHash: string,\n responseMessage: CBSocketMessage<any>,\n responseDataHash: string\n ) {\n \n if (!responseMessage.canBeStoredAsResponse ||\n (IS_NOT(responseMessage.messageData) && IS_NOT(responseMessage.messageDataHash))) {\n \n return\n \n }\n \n const localStorageKey = this.keyForRequestKeyAndRequestDataHash(requestKey, requestDataHash)\n \n var validityDate: number\n \n if (responseMessage.responseValidityDuration) {\n \n validityDate = Date.now() + responseMessage.responseValidityDuration\n \n }\n \n const storedResponseHashesDictionary = this.storedResponseHashesDictionary\n storedResponseHashesDictionary[localStorageKey] = {\n \n hash: responseDataHash,\n validityDate: validityDate!\n \n }\n \n this.saveInLocalStorage(localStorageKey, {\n \n responseMessageData: responseMessage.messageData,\n responseHash: responseDataHash\n \n })\n \n this.saveStoredResponseHashesDictionary(storedResponseHashesDictionary)\n \n }\n \n \n private saveStoredResponseHashesDictionary(storedResponseHashesDictionary: {\n [x: string]: { hash: string; validityDate: number; };\n }) {\n \n this.saveInLocalStorage(\"CBSocketResponseHashesDictionary\", storedResponseHashesDictionary)\n \n }\n \n saveInLocalStorage(key: string, object: any) {\n \n const stringToSave = JSON.stringify(object)\n \n if (stringToSave != localStorage[key]) {\n \n localStorage[key] = stringToSave\n \n }\n \n }\n \n \n socketShouldSendMessage(\n key: string,\n message: CBSocketMessage<any>,\n completionPolicy: string,\n completionFunction: CBSocketMessageCompletionFunction\n ) {\n \n var result = YES\n \n var triggerStoredResponseImmediately = NO\n \n const messageDataHash = objectHash(message.messageData || nil)\n \n const descriptorKey = \"socketMessageDescriptor_\" + key + messageDataHash\n \n this.messageDescriptors[descriptorKey] = (this.messageDescriptors[descriptorKey] || [])\n \n const hashObject = this.storedResponseHashObjectForKey(key, messageDataHash)\n message.storedResponseHash = hashObject.hash\n \n \n if (completionPolicy == CBSocketClient.completionPolicy.first) {\n \n const descriptorsForKey = (this.messageDescriptors[descriptorKey] || [])\n \n const matchingDescriptor = descriptorsForKey.find(function (descriptor, index, array) {\n return (descriptor.messageDataHash == messageDataHash)\n })\n \n if (matchingDescriptor) {\n \n result = NO\n \n }\n \n }\n \n if (completionPolicy == CBSocketClient.completionPolicy.storedOrFirst) {\n \n const descriptorsForKey = (this.messageDescriptors[descriptorKey] || [])\n \n const matchingDescriptor = descriptorsForKey.find(function (descriptor, index, array) {\n return (descriptor.messageDataHash == messageDataHash)\n })\n \n const storedResponse = IS(message.storedResponseHash)\n \n if (matchingDescriptor ||\n (storedResponse && this._verifiedResponseHashesDictionary[message.storedResponseHash!])) {\n \n result = NO\n \n triggerStoredResponseImmediately = YES\n \n }\n \n }\n \n if (completionPolicy == CBSocketClient.completionPolicy.firstOnly) {\n \n const descriptorsForKey = (this.messageDescriptors[descriptorKey] || [])\n \n const matchingDescriptor = descriptorsForKey.find(function (descriptor, index, array) {\n return (descriptor.messageDataHash == messageDataHash)\n })\n \n if (matchingDescriptor) {\n \n return NO\n \n }\n \n }\n \n \n if (hashObject && hashObject.hash && hashObject.validityDate && message.storedResponseHash &&\n this._verifiedResponseHashesDictionary[message.storedResponseHash] && hashObject.validityDate >\n Date.now()) {\n \n result = NO\n \n triggerStoredResponseImmediately = YES\n \n }\n \n \n if (IS(completionFunction)) {\n \n this.messageDescriptors[descriptorKey].push({\n \n key: key,\n message: {\n \n identifier: message.identifier,\n inResponseToIdentifier: message.inResponseToIdentifier,\n keepWaitingForResponses: message.keepWaitingForResponses\n \n },\n \n sentAtTime: Date.now(),\n \n //completionTriggered: NO,\n \n messageDataHash: messageDataHash,\n \n mainResponseReceived: NO,\n anyMainResponseReceived: NO,\n \n completionPolicy: completionPolicy,\n completionFunction: completionFunction,\n \n keepaliveHandler: undefined,\n keepaliveHandlerOverridesDefault: NO\n \n })\n \n const pushedDescriptor = this.messageDescriptors[descriptorKey].lastElement\n this._scheduleTimeoutForDescriptor(pushedDescriptor)\n \n this.keysForIdentifiers[message.identifier] = descriptorKey\n \n }\n \n \n if (triggerStoredResponseImmediately) {\n \n this.socketDidReceiveMessageForKey(\n CBSocketClient.responseMessageKey,\n {\n \n identifier: nil,\n messageData: nil,\n completionPolicy: CBSocketClient.completionPolicy.directOnly,\n \n inResponseToIdentifier: message.identifier,\n \n useStoredResponse: YES\n \n },\n nil\n )\n \n }\n \n \n return result\n \n \n }\n \n \n static defaultMultipleMessagecompletionFunction(responseMessages: any[], callcompletionFunctions: () => void) {\n callcompletionFunctions()\n }\n \n \n socketWillSendMultipleMessage(\n messageToSend: CBSocketMultipleMessage,\n completionFunction: CBSocketMultipleMessagecompletionFunction = CBSocketCallbackHolder.defaultMultipleMessagecompletionFunction\n ) {\n \n const key = CBSocketClient.multipleMessageKey\n \n const messageDataHash = objectHash(messageToSend.messageData || nil)\n \n const descriptorKey = \"socketMessageDescriptor_\" + key + messageDataHash\n \n this.messageDescriptors[descriptorKey] = (this.messageDescriptors[descriptorKey] || [])\n \n messageToSend.storedResponseHash = this.storedResponseHashObjectForKey(key, messageDataHash).hash\n \n this.messageDescriptors[descriptorKey].push({\n \n key: key,\n message: {\n \n identifier: messageToSend.identifier,\n inResponseToIdentifier: messageToSend.inResponseToIdentifier,\n keepWaitingForResponses: messageToSend.keepWaitingForResponses\n \n },\n \n sentAtTime: Date.now(),\n \n //completionTriggered: NO,\n \n messageDataHash: messageDataHash,\n \n mainResponseReceived: NO,\n anyMainResponseReceived: NO,\n \n completionPolicy: CBSocketClient.completionPolicy.directOnly,\n completionFunction: function (\n this: CBSocketCallbackHolder,\n responseMessage: CBSocketMultipleMessageObject[],\n respondWithMessage: any\n ) {\n \n completionFunction(\n responseMessage.map(function (messageObject, index, array) {\n \n return messageObject.message.messageData\n \n }),\n function (this: CBSocketCallbackHolder) {\n \n //console.log(\"Received multiple message response with length of \" + responseMessage.length +\n // \".\");\n \n // Call all completion functions\n responseMessage.forEach(function (\n this: CBSocketCallbackHolder,\n messageObject: CBSocketMultipleMessageObject,\n index: number,\n array: CBSocketMultipleMessageObject[]\n ) {\n \n this._socketClient.didReceiveMessageForKey(messageObject.key, messageObject.message)\n \n }.bind(this))\n \n }.bind(this)\n )\n \n }.bind(this),\n \n keepaliveHandler: undefined,\n keepaliveHandlerOverridesDefault: NO\n \n })\n \n this.keysForIdentifiers[messageToSend.identifier] = descriptorKey\n \n \n }\n \n \n socketDidReceiveMessageForKey(\n key: string,\n message: CBSocketMessage<any>,\n sendResponseFunction: CBSocketMessageSendResponseFunction\n ) {\n \n if (!this.isValid) {\n \n return\n \n }\n \n \n // Call static handlers\n if (this.handlers[key]) {\n \n this.handlers[key].forEach(function (\n this: CBSocketCallbackHolder,\n handler: CBSocketMessageHandlerFunction,\n index: any,\n array: any\n ) {\n \n handler(message.messageData, sendResponseFunction)\n \n }.bind(this))\n \n }\n \n if (this.onetimeHandlers[key]) {\n \n this.onetimeHandlers[key].forEach(function (\n this: CBSocketCallbackHolder,\n handler: CBSocketMessageHandlerFunction\n ) {\n \n handler(message.messageData, sendResponseFunction)\n \n }.bind(this))\n \n delete this.onetimeHandlers[key]\n \n }\n \n \n // Temporary response handlers are evaluated here\n if (message.inResponseToIdentifier &&\n (CBSocketClient.responseMessageKey == key || CBSocketClient.multipleMessageKey == key)) {\n \n // Find descriptors for the key of the message that is being responded to\n const descriptorKey = this.keysForIdentifiers[message.inResponseToIdentifier]\n const descriptorsForKey = (this.messageDescriptors[descriptorKey] || [])\n \n \n // --- Keepalive fast path ---\n // A keepalive frame must not flow through the normal completion machinery.\n // Handle it here and return early so nothing else fires.\n if (message.isKeepalive) {\n \n const payload: CBSocketKeepalivePayload = message.messageData || {}\n \n descriptorsForKey.forEach((descriptor) => {\n \n if (descriptor.message.identifier !== message.inResponseToIdentifier) {\n return\n }\n \n // Reset the client-side timeout so the request gets a full new window\n this._resetTimeoutForDescriptor(descriptor)\n \n // Fire the default handler unless the per-call handler overrides it\n if (!descriptor.keepaliveHandlerOverridesDefault) {\n this._socketClient.defaultKeepaliveHandler?.(payload)\n }\n \n // Fire the per-call handler if one was registered\n descriptor.keepaliveHandler?.(payload)\n \n })\n \n return\n \n }\n // --- End keepalive fast path ---\n \n \n // Find response data hash to check for differences\n const responseDataHash = message.messageDataHash\n \n // Remove identifier from dictionary\n if (!message.keepWaitingForResponses) {\n \n delete this.keysForIdentifiers[message.inResponseToIdentifier]\n \n // Do NOT delete the entire descriptorKey bucket here \u2014 multiple descriptors\n // with identical messageData (e.g. two concurrent requests with undefined payload)\n // share the same bucket. The per-descriptor removeElement() calls below handle\n // individual cleanup. We only delete the bucket once it is fully empty.\n \n }\n \n \n // @ts-ignore\n if (document.cbsocketclientlogmessages) {\n console.log(\n \"Callback holder is handling message. [\", descriptorsForKey.firstElement?.key, \"] \",\n message,\n \" Descriptors for key is \",\n ...descriptorsForKey\n )\n }\n \n // Function to call completion function\n const callCompletionFunction = (\n descriptor: CBSocketCallbackHolderMessageDescriptor,\n storedResponseCondition = NO\n ) => {\n \n this._cancelTimeoutForDescriptor(descriptor)\n \n var messageData = message.messageData\n \n if (message.useStoredResponse && storedResponseCondition) {\n \n messageData = this.storedResponseForKey(descriptor.key, descriptor.messageDataHash)\n \n const responseHash = this.storedResponseHashObjectForKey(\n descriptor.key,\n descriptor.messageDataHash\n ).hash\n \n const localStorageKey = this.keyForRequestKeyAndRequestDataHash(\n descriptor.key,\n descriptor.messageDataHash\n )\n \n if (message.responseValidityDuration && this.storedResponseHashesDictionary[localStorageKey]) {\n \n this.storedResponseHashesDictionary[localStorageKey].validityDate = Date.now() +\n message.responseValidityDuration\n \n this.saveStoredResponseHashesDictionary(this.storedResponseHashesDictionary)\n \n }\n \n this._verifiedResponseHashesDictionary[responseHash] = YES\n \n console.log(\"Using stored response.\")\n \n }\n \n // Call completionFunction and set response data hash\n descriptor.completionFunction(messageData, sendResponseFunction)\n descriptor.responseDataHash = responseDataHash\n \n }\n \n \n descriptorsForKey.copy().forEach(function (\n this: CBSocketCallbackHolder,\n descriptor: CBSocketCallbackHolderMessageDescriptor,\n index: number,\n array: CBSocketCallbackHolderMessageDescriptor[]\n ) {\n \n \n if ((descriptor.completionPolicy == CBSocketClient.completionPolicy.directOnly &&\n descriptor.message.identifier == message.inResponseToIdentifier) || descriptor.completionPolicy ==\n CBSocketClient.completionPolicy.first || descriptor.completionPolicy ==\n CBSocketClient.completionPolicy.firstOnly || descriptor.completionPolicy ==\n CBSocketClient.completionPolicy.storedOrFirst) {\n \n // Calling completion function and removing descriptor\n \n if (!message.keepWaitingForResponses) {\n \n this.storeResponse(descriptor.key, descriptor.messageDataHash, message, responseDataHash!)\n \n descriptorsForKey.removeElement(descriptor)\n \n sendResponseFunction.respondingToMainResponse = YES\n \n }\n \n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n }\n else if (descriptor.completionPolicy == CBSocketClient.completionPolicy.all) {\n \n // Calling completion function\n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n // Marking descriptor as having been responded to\n if (!message.keepWaitingForResponses) {\n \n if (message.inResponseToIdentifier == descriptor.message.identifier) {\n \n sendResponseFunction.respondingToMainResponse = YES\n descriptor.mainResponseReceived = YES\n descriptorsForKey.removeElement(descriptor)\n \n }\n \n descriptor.anyMainResponseReceived = YES\n \n }\n \n \n }\n else if (descriptor.completionPolicy == CBSocketClient.completionPolicy.allDifferent) {\n \n // Calling completionFunction if messageData is different from previous\n if (descriptor.responseDataHash != responseDataHash) {\n \n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n }\n \n // Marking descriptor as having been responded to\n if (!message.keepWaitingForResponses) {\n \n if (message.inResponseToIdentifier == descriptor.message.identifier) {\n \n sendResponseFunction.respondingToMainResponse = YES\n descriptor.mainResponseReceived = YES\n descriptorsForKey.removeElement(descriptor)\n \n }\n \n descriptor.anyMainResponseReceived = YES\n \n }\n \n }\n else if (descriptor.completionPolicy == CBSocketClient.completionPolicy.last &&\n descriptor.message.identifier == message.inResponseToIdentifier) {\n \n if (!message.keepWaitingForResponses) {\n \n // Marking descriptor as having been responded to\n descriptor.mainResponseReceived = YES\n descriptor.anyMainResponseReceived = YES\n \n sendResponseFunction.respondingToMainResponse = YES\n \n }\n else {\n \n descriptor.completionFunction(message.messageData, sendResponseFunction)\n \n }\n \n }\n else if (descriptor.completionPolicy == CBSocketClient.completionPolicy.firstAndLast ||\n descriptor.completionPolicy == CBSocketClient.completionPolicy.firstAndLastIfDifferent) {\n \n if (!message.keepWaitingForResponses) {\n \n // Only calling completionFunction once as a first response call\n if (!descriptor.anyMainResponseReceived) {\n \n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n }\n \n // Marking descriptor as having been responded to\n if (descriptor.message.identifier == message.inResponseToIdentifier) {\n \n descriptor.mainResponseReceived = YES\n sendResponseFunction.respondingToMainResponse = YES\n \n }\n \n descriptor.anyMainResponseReceived = YES\n \n }\n else if (descriptor.message.identifier == message.inResponseToIdentifier &&\n message.keepWaitingForResponses) {\n \n descriptor.completionFunction(message.messageData, sendResponseFunction)\n \n }\n \n }\n \n }.bind(this))\n \n \n // Last message completion policies\n \n const allResponsesReceived = descriptorsForKey.allMatch(function (descriptorObject, index, array) {\n return descriptorObject.mainResponseReceived\n })\n \n descriptorsForKey.copy().forEach(function (\n this: CBSocketCallbackHolder,\n descriptor: CBSocketCallbackHolderMessageDescriptor,\n index: number,\n array: CBSocketCallbackHolderMessageDescriptor[]\n ) {\n \n if ((descriptor.completionPolicy == CBSocketClient.completionPolicy.last ||\n descriptor.completionPolicy == CBSocketClient.completionPolicy.firstAndLast) &&\n allResponsesReceived && !message.keepWaitingForResponses) {\n \n // Calling completionFunction\n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n // Cleaning up\n descriptorsForKey.removeElement(descriptor)\n \n }\n else if (descriptor.completionPolicy == CBSocketClient.completionPolicy.firstAndLastIfDifferent &&\n allResponsesReceived && !message.keepWaitingForResponses) {\n \n // Calling completionFunction if needed\n if (descriptor.responseDataHash != responseDataHash) {\n \n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n }\n \n // Cleaning up\n descriptorsForKey.removeElement(descriptor)\n \n }\n \n }.bind(this))\n \n \n // Clean up the bucket if all descriptors have been removed\n if (!message.keepWaitingForResponses && descriptorsForKey.length === 0) {\n \n delete this.messageDescriptors[descriptorKey]\n \n }\n \n }\n \n \n }\n \n \n}\n"],
|
|
5
|
-
"mappings": "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
|
|
6
|
-
"names": ["objectHash", "_a"]
|
|
4
|
+
"sourcesContent": ["import objectHash from \"object-hash\"\nimport { FIRST, IS, IS_NOT, nil, NO, UIObject, YES } from \"../../uicore-ts\"\nimport {\n CBSocketKeepalivePayload,\n CBSocketMessage,\n CBSocketMessageCompletionFunction,\n CBSocketMessageHandlerFunction, CBSocketMessageSendResponseFunction, CBSocketMultipleMessage,\n CBSocketMultipleMessagecompletionFunction, CBSocketMultipleMessageObject\n} from \"./CBDataInterfaces\"\nimport { CBSocketClient } from \"./CBSocketClient\"\n\n\ninterface CBSocketCallbackHolderMessageDescriptor {\n \n key: string;\n message: {\n identifier: string;\n inResponseToIdentifier?: string;\n keepWaitingForResponses?: boolean;\n }\n \n sentAtTime: number;\n \n //completionTriggered: boolean;\n \n messageDataHash: string;\n \n responseDataHash?: string;\n \n mainResponseReceived: boolean;\n \n anyMainResponseReceived: boolean;\n \n completionPolicy: string;\n completionFunction: CBSocketMessageCompletionFunction;\n \n _timeoutId?: ReturnType<typeof setTimeout>;\n \n /**\n * Called when a keepalive frame arrives for this descriptor's request.\n * Registered via CBSocketRequestPromise.didReceiveKeepalive().\n */\n keepaliveHandler?: (payload: CBSocketKeepalivePayload) => void;\n \n /**\n * When true the defaultKeepaliveHandler on CBSocketClient is NOT called\n * for this descriptor \u2014 only keepaliveHandler fires.\n */\n keepaliveHandlerOverridesDefault: boolean;\n \n}\n\n\ninterface CBSocketCallbackHolderStoredResponseObject {\n \n messageKey: string;\n messageData: any;\n messageDataHash: string;\n \n}\n\n\nexport class CBSocketCallbackHolder extends UIObject {\n \n messageDescriptors: {\n \n [x: string]: CBSocketCallbackHolderMessageDescriptor[]\n \n } = {}\n \n handlers: {\n [x: string]: CBSocketMessageHandlerFunction[]\n } = {}\n \n onetimeHandlers: {\n [x: string]: CBSocketMessageHandlerFunction[]\n } = {}\n \n keysForIdentifiers: {\n \n [x: string]: string\n \n } = {}\n \n \n isValid = YES\n _storeableResponseKeys: string[] = []\n _storedResponseHashesDictionary: {\n \n [x: string]: {\n \n hash: string,\n validityDate: number\n \n }\n \n } = {}\n _verifiedResponseHashesDictionary: {\n \n [x: string]: boolean\n \n } = {}\n \n _socketClient: CBSocketClient\n \n \n constructor(socketClient: CBSocketClient, previousCallbackHolder?: CBSocketCallbackHolder) {\n \n super()\n \n this._socketClient = socketClient\n \n if (IS(previousCallbackHolder)) {\n \n this.handlers = previousCallbackHolder.handlers\n this._verifiedResponseHashesDictionary = previousCallbackHolder._verifiedResponseHashesDictionary\n \n }\n \n \n }\n \n \n triggerDisconnectHandlers() {\n \n this.messageDescriptors.forEach(\n function (this: CBSocketCallbackHolder, descriptor: CBSocketCallbackHolderMessageDescriptor, key: string) {\n \n if (!descriptor.mainResponseReceived) {\n \n this._cancelTimeoutForDescriptor(descriptor)\n \n if (typeof descriptor?.completionFunction == \"function\") {\n descriptor.completionFunction(CBSocketClient.disconnectionMessage, nil)\n }\n \n }\n \n }.bind(this))\n \n }\n \n \n registerHandler(key: string, handlerFunction: CBSocketMessageHandlerFunction) {\n \n if (!this.handlers[key]) {\n \n this.handlers[key] = []\n \n }\n \n this.handlers[key].push(handlerFunction)\n \n }\n \n registerOnetimeHandler(key: string, handlerFunction: CBSocketMessageHandlerFunction) {\n \n if (!this.onetimeHandlers[key]) {\n \n this.onetimeHandlers[key] = []\n \n }\n \n this.onetimeHandlers[key].push(handlerFunction)\n \n }\n \n \n _scheduleTimeoutForDescriptor(descriptor: CBSocketCallbackHolderMessageDescriptor) {\n \n const timeoutMs = this._socketClient.requestTimeoutMs\n \n if (!timeoutMs) {\n \n return\n \n }\n \n descriptor._timeoutId = setTimeout(() => {\n \n if (descriptor.mainResponseReceived) {\n \n return\n \n }\n \n console.warn(\n `CBSocketCallbackHolder: request \"${descriptor.key}\" timed out after ${timeoutMs} ms`\n )\n \n descriptor.mainResponseReceived = YES\n \n descriptor.completionFunction(CBSocketClient.timeoutMessage, nil)\n \n const descriptorKey = this.keysForIdentifiers[descriptor.message.identifier]\n \n if (descriptorKey) {\n \n const descriptorsForKey = this.messageDescriptors[descriptorKey]\n \n if (descriptorsForKey) {\n \n descriptorsForKey.removeElement(descriptor)\n \n if (descriptorsForKey.length === 0) {\n \n delete this.messageDescriptors[descriptorKey]\n \n }\n \n }\n \n delete this.keysForIdentifiers[descriptor.message.identifier]\n \n }\n \n }, timeoutMs)\n \n }\n \n \n _cancelTimeoutForDescriptor(descriptor: CBSocketCallbackHolderMessageDescriptor) {\n \n if (descriptor._timeoutId !== undefined) {\n \n clearTimeout(descriptor._timeoutId)\n descriptor._timeoutId = undefined\n \n }\n \n }\n \n \n /**\n * Resets the timeout for a descriptor by cancelling the current timer and\n * scheduling a fresh one. Called whenever a keepalive frame arrives so the\n * request gets a full new window to complete.\n */\n _resetTimeoutForDescriptor(descriptor: CBSocketCallbackHolderMessageDescriptor) {\n \n this._cancelTimeoutForDescriptor(descriptor)\n this._scheduleTimeoutForDescriptor(descriptor)\n \n }\n \n \n /**\n * Starts the timeout for the descriptor associated with the given identifier.\n * Called by CBSocketClient immediately after socket.emit() so the timer only\n * runs while the server is actually reachable. If the server disconnects before\n * responding, triggerDisconnectHandlers() covers cleanup without needing a timer.\n */\n scheduleTimeoutForIdentifierIfNeeded(identifier: string) {\n \n const descriptorKey = this.keysForIdentifiers[identifier]\n \n if (!descriptorKey) {\n return\n }\n \n const descriptors = this.messageDescriptors[descriptorKey]\n \n if (!descriptors) {\n return\n }\n \n const descriptor = descriptors.find(descriptor => descriptor.message.identifier === identifier)\n \n if (descriptor) {\n this._scheduleTimeoutForDescriptor(descriptor)\n }\n \n }\n \n \n get storedResponseHashesDictionary() {\n \n if (IS_NOT(this._storedResponseHashesDictionary)) {\n \n this._storedResponseHashesDictionary = JSON.parse(localStorage[\"CBSocketResponseHashesDictionary\"] || \"{}\")\n \n }\n \n return this._storedResponseHashesDictionary\n \n }\n \n storedResponseHashObjectForKey(requestKey: string, requestDataHash: string) {\n \n const localStorageKey = this.keyForRequestKeyAndRequestDataHash(requestKey, requestDataHash)\n \n const hashObject = this.storedResponseHashesDictionary[localStorageKey]\n \n const result = FIRST(hashObject, {} as any)\n \n return result\n \n }\n \n storedResponseForKey(requestKey: string, requestDataHash: string) {\n \n const localStorageKey = this.keyForRequestKeyAndRequestDataHash(requestKey, requestDataHash)\n \n const storedObject = JSON.parse(localStorage[localStorageKey] || \"{}\")\n \n return storedObject.responseMessageData\n \n }\n \n keyForRequestKeyAndRequestDataHash(requestKey: string, requestDataHash: string) {\n \n const result = \"_CBSCH_LS_key_\" + requestKey + \"_\" + requestDataHash\n \n return result\n \n }\n \n storeResponse(\n requestKey: string,\n requestDataHash: string,\n responseMessage: CBSocketMessage<any>,\n responseDataHash: string\n ) {\n \n if (!responseMessage.canBeStoredAsResponse ||\n (IS_NOT(responseMessage.messageData) && IS_NOT(responseMessage.messageDataHash))) {\n \n return\n \n }\n \n const localStorageKey = this.keyForRequestKeyAndRequestDataHash(requestKey, requestDataHash)\n \n var validityDate: number\n \n if (responseMessage.responseValidityDuration) {\n \n validityDate = Date.now() + responseMessage.responseValidityDuration\n \n }\n \n const storedResponseHashesDictionary = this.storedResponseHashesDictionary\n storedResponseHashesDictionary[localStorageKey] = {\n \n hash: responseDataHash,\n validityDate: validityDate!\n \n }\n \n this.saveInLocalStorage(localStorageKey, {\n \n responseMessageData: responseMessage.messageData,\n responseHash: responseDataHash\n \n })\n \n this.saveStoredResponseHashesDictionary(storedResponseHashesDictionary)\n \n }\n \n \n private saveStoredResponseHashesDictionary(storedResponseHashesDictionary: {\n [x: string]: { hash: string; validityDate: number; };\n }) {\n \n this.saveInLocalStorage(\"CBSocketResponseHashesDictionary\", storedResponseHashesDictionary)\n \n }\n \n saveInLocalStorage(key: string, object: any) {\n \n const stringToSave = JSON.stringify(object)\n \n if (stringToSave != localStorage[key]) {\n \n localStorage[key] = stringToSave\n \n }\n \n }\n \n \n socketShouldSendMessage(\n key: string,\n message: CBSocketMessage<any>,\n completionPolicy: string,\n completionFunction: CBSocketMessageCompletionFunction\n ) {\n \n var result = YES\n \n var triggerStoredResponseImmediately = NO\n \n const messageDataHash = objectHash(message.messageData || nil)\n \n const descriptorKey = \"socketMessageDescriptor_\" + key + messageDataHash\n \n this.messageDescriptors[descriptorKey] = (this.messageDescriptors[descriptorKey] || [])\n \n const hashObject = this.storedResponseHashObjectForKey(key, messageDataHash)\n message.storedResponseHash = hashObject.hash\n \n \n if (completionPolicy == CBSocketClient.completionPolicy.first) {\n \n const descriptorsForKey = (this.messageDescriptors[descriptorKey] || [])\n \n const matchingDescriptor = descriptorsForKey.find(function (descriptor, index, array) {\n return (descriptor.messageDataHash == messageDataHash)\n })\n \n if (matchingDescriptor) {\n \n result = NO\n \n }\n \n }\n \n if (completionPolicy == CBSocketClient.completionPolicy.storedOrFirst) {\n \n const descriptorsForKey = (this.messageDescriptors[descriptorKey] || [])\n \n const matchingDescriptor = descriptorsForKey.find(function (descriptor, index, array) {\n return (descriptor.messageDataHash == messageDataHash)\n })\n \n const storedResponse = IS(message.storedResponseHash)\n \n if (matchingDescriptor ||\n (storedResponse && this._verifiedResponseHashesDictionary[message.storedResponseHash!])) {\n \n result = NO\n \n triggerStoredResponseImmediately = YES\n \n }\n \n }\n \n if (completionPolicy == CBSocketClient.completionPolicy.firstOnly) {\n \n const descriptorsForKey = (this.messageDescriptors[descriptorKey] || [])\n \n const matchingDescriptor = descriptorsForKey.find(function (descriptor, index, array) {\n return (descriptor.messageDataHash == messageDataHash)\n })\n \n if (matchingDescriptor) {\n \n return NO\n \n }\n \n }\n \n \n if (hashObject && hashObject.hash && hashObject.validityDate && message.storedResponseHash &&\n this._verifiedResponseHashesDictionary[message.storedResponseHash] && hashObject.validityDate >\n Date.now()) {\n \n result = NO\n \n triggerStoredResponseImmediately = YES\n \n }\n \n \n if (IS(completionFunction)) {\n \n this.messageDescriptors[descriptorKey].push({\n \n key: key,\n message: {\n \n identifier: message.identifier,\n inResponseToIdentifier: message.inResponseToIdentifier,\n keepWaitingForResponses: message.keepWaitingForResponses\n \n },\n \n sentAtTime: Date.now(),\n \n //completionTriggered: NO,\n \n messageDataHash: messageDataHash,\n \n mainResponseReceived: NO,\n anyMainResponseReceived: NO,\n \n completionPolicy: completionPolicy,\n completionFunction: completionFunction,\n \n keepaliveHandler: undefined,\n keepaliveHandlerOverridesDefault: NO\n \n })\n \n const pushedDescriptor = this.messageDescriptors[descriptorKey].lastElement\n \n this.keysForIdentifiers[message.identifier] = descriptorKey\n \n }\n \n \n if (triggerStoredResponseImmediately) {\n \n this.socketDidReceiveMessageForKey(\n CBSocketClient.responseMessageKey,\n {\n \n identifier: nil,\n messageData: nil,\n completionPolicy: CBSocketClient.completionPolicy.directOnly,\n \n inResponseToIdentifier: message.identifier,\n \n useStoredResponse: YES\n \n },\n nil\n )\n \n }\n \n \n return result\n \n \n }\n \n \n static defaultMultipleMessagecompletionFunction(responseMessages: any[], callcompletionFunctions: () => void) {\n callcompletionFunctions()\n }\n \n \n socketWillSendMultipleMessage(\n messageToSend: CBSocketMultipleMessage,\n completionFunction: CBSocketMultipleMessagecompletionFunction = CBSocketCallbackHolder.defaultMultipleMessagecompletionFunction\n ) {\n \n const key = CBSocketClient.multipleMessageKey\n \n const messageDataHash = objectHash(messageToSend.messageData || nil)\n \n const descriptorKey = \"socketMessageDescriptor_\" + key + messageDataHash\n \n this.messageDescriptors[descriptorKey] = (this.messageDescriptors[descriptorKey] || [])\n \n messageToSend.storedResponseHash = this.storedResponseHashObjectForKey(key, messageDataHash).hash\n \n this.messageDescriptors[descriptorKey].push({\n \n key: key,\n message: {\n \n identifier: messageToSend.identifier,\n inResponseToIdentifier: messageToSend.inResponseToIdentifier,\n keepWaitingForResponses: messageToSend.keepWaitingForResponses\n \n },\n \n sentAtTime: Date.now(),\n \n //completionTriggered: NO,\n \n messageDataHash: messageDataHash,\n \n mainResponseReceived: NO,\n anyMainResponseReceived: NO,\n \n completionPolicy: CBSocketClient.completionPolicy.directOnly,\n completionFunction: function (\n this: CBSocketCallbackHolder,\n responseMessage: CBSocketMultipleMessageObject[],\n respondWithMessage: any\n ) {\n \n completionFunction(\n responseMessage.map(function (messageObject, index, array) {\n \n return messageObject.message.messageData\n \n }),\n function (this: CBSocketCallbackHolder) {\n \n //console.log(\"Received multiple message response with length of \" + responseMessage.length +\n // \".\");\n \n // Call all completion functions\n responseMessage.forEach(function (\n this: CBSocketCallbackHolder,\n messageObject: CBSocketMultipleMessageObject,\n index: number,\n array: CBSocketMultipleMessageObject[]\n ) {\n \n this._socketClient.didReceiveMessageForKey(messageObject.key, messageObject.message)\n \n }.bind(this))\n \n }.bind(this)\n )\n \n }.bind(this),\n \n keepaliveHandler: undefined,\n keepaliveHandlerOverridesDefault: NO\n \n })\n \n this.keysForIdentifiers[messageToSend.identifier] = descriptorKey\n \n \n }\n \n \n socketDidReceiveMessageForKey(\n key: string,\n message: CBSocketMessage<any>,\n sendResponseFunction: CBSocketMessageSendResponseFunction\n ) {\n \n if (!this.isValid) {\n \n return\n \n }\n \n \n // Call static handlers\n if (this.handlers[key]) {\n \n this.handlers[key].forEach(function (\n this: CBSocketCallbackHolder,\n handler: CBSocketMessageHandlerFunction,\n index: any,\n array: any\n ) {\n \n handler(message.messageData, sendResponseFunction)\n \n }.bind(this))\n \n }\n \n if (this.onetimeHandlers[key]) {\n \n this.onetimeHandlers[key].forEach(function (\n this: CBSocketCallbackHolder,\n handler: CBSocketMessageHandlerFunction\n ) {\n \n handler(message.messageData, sendResponseFunction)\n \n }.bind(this))\n \n delete this.onetimeHandlers[key]\n \n }\n \n \n // Temporary response handlers are evaluated here\n if (message.inResponseToIdentifier &&\n (CBSocketClient.responseMessageKey == key || CBSocketClient.multipleMessageKey == key)) {\n \n // Find descriptors for the key of the message that is being responded to\n const descriptorKey = this.keysForIdentifiers[message.inResponseToIdentifier]\n const descriptorsForKey = (this.messageDescriptors[descriptorKey] || [])\n \n \n // --- Keepalive fast path ---\n // A keepalive frame must not flow through the normal completion machinery.\n // Handle it here and return early so nothing else fires.\n if (message.isKeepalive) {\n \n const payload: CBSocketKeepalivePayload = message.messageData || {}\n \n descriptorsForKey.forEach((descriptor) => {\n \n if (descriptor.message.identifier !== message.inResponseToIdentifier) {\n return\n }\n \n // Reset the client-side timeout so the request gets a full new window\n this._resetTimeoutForDescriptor(descriptor)\n \n // Fire the default handler unless the per-call handler overrides it\n if (!descriptor.keepaliveHandlerOverridesDefault) {\n this._socketClient.defaultKeepaliveHandler?.(payload)\n }\n \n // Fire the per-call handler if one was registered\n descriptor.keepaliveHandler?.(payload)\n \n })\n \n return\n \n }\n // --- End keepalive fast path ---\n \n \n // Find response data hash to check for differences\n const responseDataHash = message.messageDataHash\n \n // Remove identifier from dictionary\n if (!message.keepWaitingForResponses) {\n \n delete this.keysForIdentifiers[message.inResponseToIdentifier]\n \n // Do NOT delete the entire descriptorKey bucket here \u2014 multiple descriptors\n // with identical messageData (e.g. two concurrent requests with undefined payload)\n // share the same bucket. The per-descriptor removeElement() calls below handle\n // individual cleanup. We only delete the bucket once it is fully empty.\n \n }\n \n \n // @ts-ignore\n if (document.cbsocketclientlogmessages) {\n console.log(\n \"Callback holder is handling message. [\", descriptorsForKey.firstElement?.key, \"] \",\n message,\n \" Descriptors for key is \",\n ...descriptorsForKey\n )\n }\n \n // Function to call completion function\n const callCompletionFunction = (\n descriptor: CBSocketCallbackHolderMessageDescriptor,\n storedResponseCondition = NO\n ) => {\n \n this._cancelTimeoutForDescriptor(descriptor)\n \n var messageData = message.messageData\n \n if (message.useStoredResponse && storedResponseCondition) {\n \n messageData = this.storedResponseForKey(descriptor.key, descriptor.messageDataHash)\n \n const responseHash = this.storedResponseHashObjectForKey(\n descriptor.key,\n descriptor.messageDataHash\n ).hash\n \n const localStorageKey = this.keyForRequestKeyAndRequestDataHash(\n descriptor.key,\n descriptor.messageDataHash\n )\n \n if (message.responseValidityDuration && this.storedResponseHashesDictionary[localStorageKey]) {\n \n this.storedResponseHashesDictionary[localStorageKey].validityDate = Date.now() +\n message.responseValidityDuration\n \n this.saveStoredResponseHashesDictionary(this.storedResponseHashesDictionary)\n \n }\n \n this._verifiedResponseHashesDictionary[responseHash] = YES\n \n console.log(\"Using stored response.\")\n \n }\n \n // Call completionFunction and set response data hash\n descriptor.completionFunction(messageData, sendResponseFunction)\n descriptor.responseDataHash = responseDataHash\n \n }\n \n \n descriptorsForKey.copy().forEach(function (\n this: CBSocketCallbackHolder,\n descriptor: CBSocketCallbackHolderMessageDescriptor,\n index: number,\n array: CBSocketCallbackHolderMessageDescriptor[]\n ) {\n \n \n if ((descriptor.completionPolicy == CBSocketClient.completionPolicy.directOnly &&\n descriptor.message.identifier == message.inResponseToIdentifier) || descriptor.completionPolicy ==\n CBSocketClient.completionPolicy.first || descriptor.completionPolicy ==\n CBSocketClient.completionPolicy.firstOnly || descriptor.completionPolicy ==\n CBSocketClient.completionPolicy.storedOrFirst) {\n \n // Calling completion function and removing descriptor\n \n if (!message.keepWaitingForResponses) {\n \n this.storeResponse(descriptor.key, descriptor.messageDataHash, message, responseDataHash!)\n \n descriptorsForKey.removeElement(descriptor)\n \n sendResponseFunction.respondingToMainResponse = YES\n \n }\n \n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n }\n else if (descriptor.completionPolicy == CBSocketClient.completionPolicy.all) {\n \n // Calling completion function\n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n // Marking descriptor as having been responded to\n if (!message.keepWaitingForResponses) {\n \n if (message.inResponseToIdentifier == descriptor.message.identifier) {\n \n sendResponseFunction.respondingToMainResponse = YES\n descriptor.mainResponseReceived = YES\n descriptorsForKey.removeElement(descriptor)\n \n }\n \n descriptor.anyMainResponseReceived = YES\n \n }\n \n \n }\n else if (descriptor.completionPolicy == CBSocketClient.completionPolicy.allDifferent) {\n \n // Calling completionFunction if messageData is different from previous\n if (descriptor.responseDataHash != responseDataHash) {\n \n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n }\n \n // Marking descriptor as having been responded to\n if (!message.keepWaitingForResponses) {\n \n if (message.inResponseToIdentifier == descriptor.message.identifier) {\n \n sendResponseFunction.respondingToMainResponse = YES\n descriptor.mainResponseReceived = YES\n descriptorsForKey.removeElement(descriptor)\n \n }\n \n descriptor.anyMainResponseReceived = YES\n \n }\n \n }\n else if (descriptor.completionPolicy == CBSocketClient.completionPolicy.last &&\n descriptor.message.identifier == message.inResponseToIdentifier) {\n \n if (!message.keepWaitingForResponses) {\n \n // Marking descriptor as having been responded to\n descriptor.mainResponseReceived = YES\n descriptor.anyMainResponseReceived = YES\n \n sendResponseFunction.respondingToMainResponse = YES\n \n }\n else {\n \n descriptor.completionFunction(message.messageData, sendResponseFunction)\n \n }\n \n }\n else if (descriptor.completionPolicy == CBSocketClient.completionPolicy.firstAndLast ||\n descriptor.completionPolicy == CBSocketClient.completionPolicy.firstAndLastIfDifferent) {\n \n if (!message.keepWaitingForResponses) {\n \n // Only calling completionFunction once as a first response call\n if (!descriptor.anyMainResponseReceived) {\n \n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n }\n \n // Marking descriptor as having been responded to\n if (descriptor.message.identifier == message.inResponseToIdentifier) {\n \n descriptor.mainResponseReceived = YES\n sendResponseFunction.respondingToMainResponse = YES\n \n }\n \n descriptor.anyMainResponseReceived = YES\n \n }\n else if (descriptor.message.identifier == message.inResponseToIdentifier &&\n message.keepWaitingForResponses) {\n \n descriptor.completionFunction(message.messageData, sendResponseFunction)\n \n }\n \n }\n \n }.bind(this))\n \n \n // Last message completion policies\n \n const allResponsesReceived = descriptorsForKey.allMatch(function (descriptorObject, index, array) {\n return descriptorObject.mainResponseReceived\n })\n \n descriptorsForKey.copy().forEach(function (\n this: CBSocketCallbackHolder,\n descriptor: CBSocketCallbackHolderMessageDescriptor,\n index: number,\n array: CBSocketCallbackHolderMessageDescriptor[]\n ) {\n \n if ((descriptor.completionPolicy == CBSocketClient.completionPolicy.last ||\n descriptor.completionPolicy == CBSocketClient.completionPolicy.firstAndLast) &&\n allResponsesReceived && !message.keepWaitingForResponses) {\n \n // Calling completionFunction\n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n // Cleaning up\n descriptorsForKey.removeElement(descriptor)\n \n }\n else if (descriptor.completionPolicy == CBSocketClient.completionPolicy.firstAndLastIfDifferent &&\n allResponsesReceived && !message.keepWaitingForResponses) {\n \n // Calling completionFunction if needed\n if (descriptor.responseDataHash != responseDataHash) {\n \n callCompletionFunction(descriptor, !message.keepWaitingForResponses)\n \n }\n \n // Cleaning up\n descriptorsForKey.removeElement(descriptor)\n \n }\n \n }.bind(this))\n \n \n // Clean up the bucket if all descriptors have been removed\n if (!message.keepWaitingForResponses && descriptorsForKey.length === 0) {\n \n delete this.messageDescriptors[descriptorKey]\n \n }\n \n }\n \n \n }\n \n \n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["descriptor", "objectHash", "_a"]
|
|
7
7
|
}
|
|
@@ -56,7 +56,8 @@ export declare class CBSocketClient extends UIObject {
|
|
|
56
56
|
/**
|
|
57
57
|
* How long (in milliseconds) to wait for a server response before treating
|
|
58
58
|
* the request as failed. Set to 0 to disable timeouts entirely.
|
|
59
|
-
* Default: 30 000 ms (30 seconds)
|
|
59
|
+
* Default: 30 000 ms (30 seconds) in production; disabled in development
|
|
60
|
+
* so that breakpoints do not cause spurious request failures.
|
|
60
61
|
*
|
|
61
62
|
* Each keepalive frame from the server resets this window, so long-running
|
|
62
63
|
* requests only time out if the server goes completely silent for this duration.
|
|
@@ -46,7 +46,8 @@ const _CBSocketClient = class _CBSocketClient extends import_uicore_ts.UIObject
|
|
|
46
46
|
/**
|
|
47
47
|
* How long (in milliseconds) to wait for a server response before treating
|
|
48
48
|
* the request as failed. Set to 0 to disable timeouts entirely.
|
|
49
|
-
* Default: 30 000 ms (30 seconds)
|
|
49
|
+
* Default: 30 000 ms (30 seconds) in production; disabled in development
|
|
50
|
+
* so that breakpoints do not cause spurious request failures.
|
|
50
51
|
*
|
|
51
52
|
* Each keepalive frame from the server resets this window, so long-running
|
|
52
53
|
* requests only time out if the server goes completely silent for this duration.
|
|
@@ -54,6 +55,7 @@ const _CBSocketClient = class _CBSocketClient extends import_uicore_ts.UIObject
|
|
|
54
55
|
this.requestTimeoutMs = 3e4;
|
|
55
56
|
this._core = core;
|
|
56
57
|
this._socket = (0, import_socket.io)();
|
|
58
|
+
this.requestTimeoutMs = 0;
|
|
57
59
|
this.socket.on("connect", () => {
|
|
58
60
|
console.log("Socket.io connected to server. clientID = ", this.socket, " socketID = ", this.socket);
|
|
59
61
|
this.sendUnsentMessages();
|
|
@@ -165,6 +167,9 @@ const _CBSocketClient = class _CBSocketClient extends import_uicore_ts.UIObject
|
|
|
165
167
|
);
|
|
166
168
|
}
|
|
167
169
|
this.socket.emit(_CBSocketClient.multipleMessageKey, messageObject);
|
|
170
|
+
groupedMessages.forEach((groupedMessage) => {
|
|
171
|
+
this._callbackHolder.scheduleTimeoutForIdentifierIfNeeded(groupedMessage.message.identifier);
|
|
172
|
+
});
|
|
168
173
|
didSendFunctions.forEach((didSendFunction, index, array) => {
|
|
169
174
|
didSendFunction();
|
|
170
175
|
});
|
|
@@ -263,6 +268,7 @@ const _CBSocketClient = class _CBSocketClient extends import_uicore_ts.UIObject
|
|
|
263
268
|
);
|
|
264
269
|
}
|
|
265
270
|
this.socket.emit(key, messageObject);
|
|
271
|
+
this._callbackHolder.scheduleTimeoutForIdentifierIfNeeded(identifier);
|
|
266
272
|
}
|
|
267
273
|
didSendFunction();
|
|
268
274
|
} else {
|
|
@@ -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 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": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA0D;AAC1D,uBAAgG;AAChG,oBAAuB;AAcvB,oCAAuC;AAkChC,SAAS,gBAAgB,QAAmD;AAE/E,QAAM,aAAU,qBAAG,MAAM,KAAK,OAAO;AAErC,SAAO;AAEX;AAEO,SAAS,oBAAoB,QAAa;AAE7C,SAAO,CAAC,gBAAgB,MAAM;AAElC;AA2BO,MAAM,kBAAN,MAAM,wBAAuB,0BAAS;AAAA,
|
|
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) in production; disabled in development\n * so that breakpoints do not cause spurious request failures.\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 = 30000\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 /// #if DEV\n this.requestTimeoutMs = 0\n /// #endif\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 groupedMessages.forEach((groupedMessage) => {\n this._callbackHolder.scheduleTimeoutForIdentifierIfNeeded(groupedMessage.message.identifier)\n })\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) => {\n capturedIdentifier = identifier\n }\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 this._callbackHolder.scheduleTimeoutForIdentifierIfNeeded(identifier)\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
package/scripts/CBCore.ts
CHANGED
|
@@ -244,6 +244,35 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Starts the timeout for the descriptor associated with the given identifier.
|
|
249
|
+
* Called by CBSocketClient immediately after socket.emit() so the timer only
|
|
250
|
+
* runs while the server is actually reachable. If the server disconnects before
|
|
251
|
+
* responding, triggerDisconnectHandlers() covers cleanup without needing a timer.
|
|
252
|
+
*/
|
|
253
|
+
scheduleTimeoutForIdentifierIfNeeded(identifier: string) {
|
|
254
|
+
|
|
255
|
+
const descriptorKey = this.keysForIdentifiers[identifier]
|
|
256
|
+
|
|
257
|
+
if (!descriptorKey) {
|
|
258
|
+
return
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const descriptors = this.messageDescriptors[descriptorKey]
|
|
262
|
+
|
|
263
|
+
if (!descriptors) {
|
|
264
|
+
return
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const descriptor = descriptors.find(descriptor => descriptor.message.identifier === identifier)
|
|
268
|
+
|
|
269
|
+
if (descriptor) {
|
|
270
|
+
this._scheduleTimeoutForDescriptor(descriptor)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
|
|
247
276
|
get storedResponseHashesDictionary() {
|
|
248
277
|
|
|
249
278
|
if (IS_NOT(this._storedResponseHashesDictionary)) {
|
|
@@ -468,7 +497,6 @@ export class CBSocketCallbackHolder extends UIObject {
|
|
|
468
497
|
})
|
|
469
498
|
|
|
470
499
|
const pushedDescriptor = this.messageDescriptors[descriptorKey].lastElement
|
|
471
|
-
this._scheduleTimeoutForDescriptor(pushedDescriptor)
|
|
472
500
|
|
|
473
501
|
this.keysForIdentifiers[message.identifier] = descriptorKey
|
|
474
502
|
|
|
@@ -131,13 +131,14 @@ export class CBSocketClient extends UIObject {
|
|
|
131
131
|
/**
|
|
132
132
|
* How long (in milliseconds) to wait for a server response before treating
|
|
133
133
|
* the request as failed. Set to 0 to disable timeouts entirely.
|
|
134
|
-
* Default: 30 000 ms (30 seconds)
|
|
134
|
+
* Default: 30 000 ms (30 seconds) in production; disabled in development
|
|
135
|
+
* so that breakpoints do not cause spurious request failures.
|
|
135
136
|
*
|
|
136
137
|
* Each keepalive frame from the server resets this window, so long-running
|
|
137
138
|
* requests only time out if the server goes completely silent for this duration.
|
|
138
139
|
*/
|
|
139
|
-
requestTimeoutMs: number =
|
|
140
|
-
|
|
140
|
+
requestTimeoutMs: number = 30000
|
|
141
|
+
|
|
141
142
|
/**
|
|
142
143
|
* Application-level keepalive handler. Called for every keepalive frame
|
|
143
144
|
* received on any request, unless the per-call handler was registered with
|
|
@@ -156,6 +157,10 @@ export class CBSocketClient extends UIObject {
|
|
|
156
157
|
this._core = core
|
|
157
158
|
this._socket = io()
|
|
158
159
|
|
|
160
|
+
/// #if DEV
|
|
161
|
+
this.requestTimeoutMs = 0
|
|
162
|
+
/// #endif
|
|
163
|
+
|
|
159
164
|
this.socket.on("connect", () => {
|
|
160
165
|
|
|
161
166
|
console.log("Socket.io connected to server. clientID = ", this.socket, " socketID = ", this.socket)
|
|
@@ -355,6 +360,10 @@ export class CBSocketClient extends UIObject {
|
|
|
355
360
|
|
|
356
361
|
this.socket.emit(CBSocketClient.multipleMessageKey, messageObject)
|
|
357
362
|
|
|
363
|
+
groupedMessages.forEach((groupedMessage) => {
|
|
364
|
+
this._callbackHolder.scheduleTimeoutForIdentifierIfNeeded(groupedMessage.message.identifier)
|
|
365
|
+
})
|
|
366
|
+
|
|
358
367
|
|
|
359
368
|
didSendFunctions.forEach((didSendFunction, index, array) => {
|
|
360
369
|
didSendFunction()
|
|
@@ -428,19 +437,19 @@ export class CBSocketClient extends UIObject {
|
|
|
428
437
|
errorResult: any,
|
|
429
438
|
respondWithMessage: CBSocketMessageSendResponseFunction
|
|
430
439
|
}> {
|
|
431
|
-
|
|
440
|
+
|
|
432
441
|
// The identifier is assigned synchronously inside _sendMessageForKey.
|
|
433
442
|
// We capture it via didObtainIdentifier so we can look up the descriptor
|
|
434
443
|
// immediately after the send, before any async gap.
|
|
435
444
|
let capturedIdentifier: string | undefined
|
|
436
|
-
|
|
445
|
+
|
|
437
446
|
const basePromise = new Promise<{
|
|
438
447
|
responseMessage: any,
|
|
439
448
|
result: any,
|
|
440
449
|
errorResult: any,
|
|
441
450
|
respondWithMessage: CBSocketMessageSendResponseFunction
|
|
442
451
|
}>((resolve, reject) => {
|
|
443
|
-
|
|
452
|
+
|
|
444
453
|
this._sendMessageForKey(
|
|
445
454
|
key as string,
|
|
446
455
|
message,
|
|
@@ -450,41 +459,43 @@ export class CBSocketClient extends UIObject {
|
|
|
450
459
|
isUserBound,
|
|
451
460
|
nil,
|
|
452
461
|
(responseMessage, respondWithMessage) => resolve({
|
|
453
|
-
|
|
462
|
+
|
|
454
463
|
responseMessage: responseMessage,
|
|
455
464
|
result: IF(IS_NOT_SOCKET_ERROR(responseMessage))(() => responseMessage).ELSE(RETURNER(undefined)),
|
|
456
465
|
errorResult: IF(IS_SOCKET_ERROR(responseMessage))(() => responseMessage).ELSE(RETURNER(undefined)),
|
|
457
|
-
|
|
466
|
+
|
|
458
467
|
respondWithMessage: respondWithMessage
|
|
459
|
-
|
|
468
|
+
|
|
460
469
|
}),
|
|
461
|
-
(identifier) => {
|
|
470
|
+
(identifier) => {
|
|
471
|
+
capturedIdentifier = identifier
|
|
472
|
+
}
|
|
462
473
|
)
|
|
463
|
-
|
|
474
|
+
|
|
464
475
|
})
|
|
465
|
-
|
|
476
|
+
|
|
466
477
|
const requestPromise = basePromise as CBSocketRequestPromise<any>
|
|
467
|
-
|
|
478
|
+
|
|
468
479
|
requestPromise.didReceiveKeepalive = (
|
|
469
480
|
handler: (payload: CBSocketKeepalivePayload) => void,
|
|
470
481
|
extendsDefaultHandler = YES
|
|
471
482
|
): CBSocketRequestPromise<any> => {
|
|
472
|
-
|
|
483
|
+
|
|
473
484
|
// The descriptor is pushed synchronously before _sendMessageForKey returns,
|
|
474
485
|
// so capturedIdentifier is already set at this point.
|
|
475
486
|
if (capturedIdentifier) {
|
|
476
487
|
this._attachKeepaliveHandlerForIdentifier(capturedIdentifier, handler, extendsDefaultHandler)
|
|
477
488
|
}
|
|
478
|
-
|
|
489
|
+
|
|
479
490
|
return requestPromise
|
|
480
|
-
|
|
491
|
+
|
|
481
492
|
}
|
|
482
|
-
|
|
493
|
+
|
|
483
494
|
return requestPromise
|
|
484
|
-
|
|
495
|
+
|
|
485
496
|
}
|
|
486
|
-
|
|
487
|
-
|
|
497
|
+
|
|
498
|
+
|
|
488
499
|
/**
|
|
489
500
|
* Finds the descriptor for the given request identifier and attaches the
|
|
490
501
|
* keepalive handler fields to it.
|
|
@@ -494,27 +505,27 @@ export class CBSocketClient extends UIObject {
|
|
|
494
505
|
handler: (payload: CBSocketKeepalivePayload) => void,
|
|
495
506
|
extendsDefaultHandler: boolean
|
|
496
507
|
) {
|
|
497
|
-
|
|
508
|
+
|
|
498
509
|
const descriptorKey = this._callbackHolder.keysForIdentifiers[identifier]
|
|
499
510
|
if (!descriptorKey) {
|
|
500
511
|
return
|
|
501
512
|
}
|
|
502
|
-
|
|
513
|
+
|
|
503
514
|
const descriptors = this._callbackHolder.messageDescriptors[descriptorKey]
|
|
504
515
|
if (!descriptors) {
|
|
505
516
|
return
|
|
506
517
|
}
|
|
507
|
-
|
|
518
|
+
|
|
508
519
|
const descriptor = descriptors.find(d => d.message.identifier === identifier)
|
|
509
520
|
if (!descriptor) {
|
|
510
521
|
return
|
|
511
522
|
}
|
|
512
|
-
|
|
523
|
+
|
|
513
524
|
descriptor.keepaliveHandler = handler
|
|
514
525
|
descriptor.keepaliveHandlerOverridesDefault = !extendsDefaultHandler
|
|
515
|
-
|
|
526
|
+
|
|
516
527
|
}
|
|
517
|
-
|
|
528
|
+
|
|
518
529
|
|
|
519
530
|
_sendMessageForKey(
|
|
520
531
|
key: string,
|
|
@@ -537,7 +548,7 @@ export class CBSocketClient extends UIObject {
|
|
|
537
548
|
if (this._isConnectionEstablished && !this._collectMessagesToSendLater) {
|
|
538
549
|
|
|
539
550
|
const identifier = MAKE_ID()
|
|
540
|
-
|
|
551
|
+
|
|
541
552
|
didObtainIdentifier?.(identifier)
|
|
542
553
|
|
|
543
554
|
const messageObject: CBSocketMessage<any> = {
|
|
@@ -568,6 +579,7 @@ export class CBSocketClient extends UIObject {
|
|
|
568
579
|
}
|
|
569
580
|
|
|
570
581
|
this.socket.emit(key, messageObject)
|
|
582
|
+
this._callbackHolder.scheduleTimeoutForIdentifierIfNeeded(identifier)
|
|
571
583
|
|
|
572
584
|
}
|
|
573
585
|
|