cbcore-ts 1.0.58 → 1.0.61
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 +97 -0
- package/compiledScripts/CBCore.js +55 -0
- package/compiledScripts/CBCore.js.map +2 -2
- package/package.json +1 -1
- package/scripts/CBCore.ts +113 -24
|
@@ -8,6 +8,56 @@ declare interface CBDialogViewShower {
|
|
|
8
8
|
showActionIndicatorDialog(message: string, dismissCallback?: Function): void;
|
|
9
9
|
hideActionIndicatorDialog(): void;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* CBCore — Application session model and library entry point.
|
|
13
|
+
*
|
|
14
|
+
* CBCore is a general-purpose library class. It must not contain any
|
|
15
|
+
* project-specific business logic. To extend it for a specific project,
|
|
16
|
+
* subclass CBCore and register the subclass as the singleton before any
|
|
17
|
+
* other code accesses `CBCore.sharedInstance`.
|
|
18
|
+
*
|
|
19
|
+
* ## Extension pattern
|
|
20
|
+
*
|
|
21
|
+
* 1. Subclass CBCore in your project:
|
|
22
|
+
*
|
|
23
|
+
* ```typescript
|
|
24
|
+
* class MyAppCore extends CBCore {
|
|
25
|
+
*
|
|
26
|
+
* // Additional session-level state goes here.
|
|
27
|
+
* mySessionData: MySessionData | undefined = undefined
|
|
28
|
+
*
|
|
29
|
+
* // Override didSetUserProfile to fetch session data before the
|
|
30
|
+
* // userDidLogIn broadcast fires. Call super only after your data
|
|
31
|
+
* // is ready so that every listener receives a fully populated core.
|
|
32
|
+
* override async didSetUserProfile() {
|
|
33
|
+
* if (IS(this.userProfile)) {
|
|
34
|
+
* this.mySessionData = await fetchMySessionData()
|
|
35
|
+
* }
|
|
36
|
+
* else {
|
|
37
|
+
* this.mySessionData = undefined
|
|
38
|
+
* }
|
|
39
|
+
* super.didSetUserProfile()
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* // Expose a typed singleton so callers never need CBCore.sharedInstance.
|
|
43
|
+
* static override get sharedInstance(): MyAppCore {
|
|
44
|
+
* return CBCore.sharedInstance as MyAppCore
|
|
45
|
+
* }
|
|
46
|
+
*
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* 2. Register the subclass at app startup, before UICore is initialised:
|
|
51
|
+
*
|
|
52
|
+
* ```typescript
|
|
53
|
+
* CBCore.setSharedInstance(new MyAppCore())
|
|
54
|
+
* CBCore.initIfNeededWithViewCore(new UICore(...))
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* 3. From that point on, every call to `CBCore.sharedInstance` — including
|
|
58
|
+
* calls made internally by the library — returns the MyAppCore instance.
|
|
59
|
+
* Project code should call `MyAppCore.sharedInstance` for the typed version.
|
|
60
|
+
*/
|
|
11
61
|
export declare class CBCore extends UIObject {
|
|
12
62
|
private static _sharedInstance;
|
|
13
63
|
viewCores: UICore[];
|
|
@@ -20,7 +70,31 @@ export declare class CBCore extends UIObject {
|
|
|
20
70
|
dialogViewShowerClass: CBDialogViewShower;
|
|
21
71
|
constructor();
|
|
22
72
|
static initIfNeededWithViewCore(viewCore: UICore): void;
|
|
73
|
+
/**
|
|
74
|
+
* Returns the shared singleton instance.
|
|
75
|
+
*
|
|
76
|
+
* If `setSharedInstance` was called before this getter was first accessed,
|
|
77
|
+
* that instance is returned. Otherwise a default `CBCore` is created.
|
|
78
|
+
* Library-internal code always goes through this getter, so registering a
|
|
79
|
+
* subclass via `setSharedInstance` is sufficient to replace the singleton
|
|
80
|
+
* for the entire session.
|
|
81
|
+
*/
|
|
23
82
|
static get sharedInstance(): CBCore;
|
|
83
|
+
/**
|
|
84
|
+
* Registers a subclass instance as the application singleton.
|
|
85
|
+
*
|
|
86
|
+
* Call this once at app startup, before `CBCore.sharedInstance` or
|
|
87
|
+
* `CBCore.initIfNeededWithViewCore` are first accessed. Calling it after
|
|
88
|
+
* the singleton has already been created has no effect and will throw in
|
|
89
|
+
* development to catch accidental misuse.
|
|
90
|
+
*
|
|
91
|
+
* ```typescript
|
|
92
|
+
* // App entry point — must be the very first thing that runs.
|
|
93
|
+
* CBCore.setSharedInstance(new MyAppCore())
|
|
94
|
+
* CBCore.initIfNeededWithViewCore(new UICore("root", RootViewController))
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
static setSharedInstance(instance: CBCore): void;
|
|
24
98
|
static broadcastEventName: {
|
|
25
99
|
readonly userDidLogIn: "UserDidLogIn";
|
|
26
100
|
readonly userDidLogOut: "UserDidLogOut";
|
|
@@ -35,6 +109,29 @@ export declare class CBCore extends UIObject {
|
|
|
35
109
|
private _userProfile;
|
|
36
110
|
get userProfile(): CBUserProfile;
|
|
37
111
|
set userProfile(userProfile: CBUserProfile);
|
|
112
|
+
/**
|
|
113
|
+
* Called whenever `userProfile` is assigned.
|
|
114
|
+
*
|
|
115
|
+
* The default implementation derives `isUserLoggedIn` from the profile
|
|
116
|
+
* and triggers the login/logout broadcast via `didSetIsUserLoggedIn`.
|
|
117
|
+
*
|
|
118
|
+
* Subclasses may override this to fetch additional session data before
|
|
119
|
+
* the broadcast fires. The override must be `async` and must call
|
|
120
|
+
* `super.didSetUserProfile()` after it has finished populating any
|
|
121
|
+
* extra state, so that all broadcast listeners receive a complete core:
|
|
122
|
+
*
|
|
123
|
+
* ```typescript
|
|
124
|
+
* override async didSetUserProfile() {
|
|
125
|
+
* if (IS(this.userProfile)) {
|
|
126
|
+
* this.companyStatus = (await SocketClient.CurrentUserStatusInCompany()).result
|
|
127
|
+
* }
|
|
128
|
+
* else {
|
|
129
|
+
* this.companyStatus = undefined
|
|
130
|
+
* }
|
|
131
|
+
* super.didSetUserProfile() // broadcast fires here
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
38
135
|
didSetUserProfile(): void;
|
|
39
136
|
set languageKey(languageKey: string);
|
|
40
137
|
get languageKey(): string;
|
|
@@ -53,12 +53,44 @@ const _CBCore = class _CBCore extends import_uicore_ts2.UIObject {
|
|
|
53
53
|
static initIfNeededWithViewCore(viewCore) {
|
|
54
54
|
_CBCore.sharedInstance.viewCores.push(viewCore);
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Returns the shared singleton instance.
|
|
58
|
+
*
|
|
59
|
+
* If `setSharedInstance` was called before this getter was first accessed,
|
|
60
|
+
* that instance is returned. Otherwise a default `CBCore` is created.
|
|
61
|
+
* Library-internal code always goes through this getter, so registering a
|
|
62
|
+
* subclass via `setSharedInstance` is sufficient to replace the singleton
|
|
63
|
+
* for the entire session.
|
|
64
|
+
*/
|
|
56
65
|
static get sharedInstance() {
|
|
57
66
|
if (!_CBCore._sharedInstance) {
|
|
58
67
|
_CBCore._sharedInstance = new _CBCore();
|
|
59
68
|
}
|
|
60
69
|
return _CBCore._sharedInstance;
|
|
61
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Registers a subclass instance as the application singleton.
|
|
73
|
+
*
|
|
74
|
+
* Call this once at app startup, before `CBCore.sharedInstance` or
|
|
75
|
+
* `CBCore.initIfNeededWithViewCore` are first accessed. Calling it after
|
|
76
|
+
* the singleton has already been created has no effect and will throw in
|
|
77
|
+
* development to catch accidental misuse.
|
|
78
|
+
*
|
|
79
|
+
* ```typescript
|
|
80
|
+
* // App entry point — must be the very first thing that runs.
|
|
81
|
+
* CBCore.setSharedInstance(new MyAppCore())
|
|
82
|
+
* CBCore.initIfNeededWithViewCore(new UICore("root", RootViewController))
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
static setSharedInstance(instance) {
|
|
86
|
+
if (_CBCore._sharedInstance) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
"CBCore.setSharedInstance must be called before sharedInstance is first accessed. Move the call to the very top of your app entry point."
|
|
89
|
+
);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
_CBCore._sharedInstance = instance;
|
|
93
|
+
}
|
|
62
94
|
broadcastMessageInRootViewTree(message) {
|
|
63
95
|
this.viewCores.everyElement.rootViewController.view.broadcastEventInSubtree(message);
|
|
64
96
|
}
|
|
@@ -111,6 +143,29 @@ const _CBCore = class _CBCore extends import_uicore_ts2.UIObject {
|
|
|
111
143
|
this._userProfile = userProfile;
|
|
112
144
|
this.didSetUserProfile();
|
|
113
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Called whenever `userProfile` is assigned.
|
|
148
|
+
*
|
|
149
|
+
* The default implementation derives `isUserLoggedIn` from the profile
|
|
150
|
+
* and triggers the login/logout broadcast via `didSetIsUserLoggedIn`.
|
|
151
|
+
*
|
|
152
|
+
* Subclasses may override this to fetch additional session data before
|
|
153
|
+
* the broadcast fires. The override must be `async` and must call
|
|
154
|
+
* `super.didSetUserProfile()` after it has finished populating any
|
|
155
|
+
* extra state, so that all broadcast listeners receive a complete core:
|
|
156
|
+
*
|
|
157
|
+
* ```typescript
|
|
158
|
+
* override async didSetUserProfile() {
|
|
159
|
+
* if (IS(this.userProfile)) {
|
|
160
|
+
* this.companyStatus = (await SocketClient.CurrentUserStatusInCompany()).result
|
|
161
|
+
* }
|
|
162
|
+
* else {
|
|
163
|
+
* this.companyStatus = undefined
|
|
164
|
+
* }
|
|
165
|
+
* super.didSetUserProfile() // broadcast fires here
|
|
166
|
+
* }
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
114
169
|
didSetUserProfile() {
|
|
115
170
|
this.isUserLoggedIn = (0, import_uicore_ts2.IS)(this.userProfile);
|
|
116
171
|
}
|
|
@@ -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\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 //console.log(\"\" + event.key + \" changed to \" + event.newValue + \" from \" + event.oldValue);\n \n \n if (event.key == \"CBLanguageKey\") {\n this.didSetLanguageKey()\n }\n \n }.bind(this))\n \n \n //this.checkIfUserIsAuthenticated();\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 static get sharedInstance() {\n if (!CBCore._sharedInstance) {\n CBCore._sharedInstance = new CBCore()\n }\n return CBCore._sharedInstance\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.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 }\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 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\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAAmB;AACnB,IAAAA,oBAAqG;AAErG,+BAAkC;AAClC,4BAA+B;AAC/B,4BAA+B;
|
|
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.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 }\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\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_uicore_ts"]
|
|
7
7
|
}
|
package/package.json
CHANGED
package/scripts/CBCore.ts
CHANGED
|
@@ -23,6 +23,56 @@ declare interface CBDialogViewShower {
|
|
|
23
23
|
declare const CBCoreInitializerObject: any
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* CBCore — Application session model and library entry point.
|
|
28
|
+
*
|
|
29
|
+
* CBCore is a general-purpose library class. It must not contain any
|
|
30
|
+
* project-specific business logic. To extend it for a specific project,
|
|
31
|
+
* subclass CBCore and register the subclass as the singleton before any
|
|
32
|
+
* other code accesses `CBCore.sharedInstance`.
|
|
33
|
+
*
|
|
34
|
+
* ## Extension pattern
|
|
35
|
+
*
|
|
36
|
+
* 1. Subclass CBCore in your project:
|
|
37
|
+
*
|
|
38
|
+
* ```typescript
|
|
39
|
+
* class MyAppCore extends CBCore {
|
|
40
|
+
*
|
|
41
|
+
* // Additional session-level state goes here.
|
|
42
|
+
* mySessionData: MySessionData | undefined = undefined
|
|
43
|
+
*
|
|
44
|
+
* // Override didSetUserProfile to fetch session data before the
|
|
45
|
+
* // userDidLogIn broadcast fires. Call super only after your data
|
|
46
|
+
* // is ready so that every listener receives a fully populated core.
|
|
47
|
+
* override async didSetUserProfile() {
|
|
48
|
+
* if (IS(this.userProfile)) {
|
|
49
|
+
* this.mySessionData = await fetchMySessionData()
|
|
50
|
+
* }
|
|
51
|
+
* else {
|
|
52
|
+
* this.mySessionData = undefined
|
|
53
|
+
* }
|
|
54
|
+
* super.didSetUserProfile()
|
|
55
|
+
* }
|
|
56
|
+
*
|
|
57
|
+
* // Expose a typed singleton so callers never need CBCore.sharedInstance.
|
|
58
|
+
* static override get sharedInstance(): MyAppCore {
|
|
59
|
+
* return CBCore.sharedInstance as MyAppCore
|
|
60
|
+
* }
|
|
61
|
+
*
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* 2. Register the subclass at app startup, before UICore is initialised:
|
|
66
|
+
*
|
|
67
|
+
* ```typescript
|
|
68
|
+
* CBCore.setSharedInstance(new MyAppCore())
|
|
69
|
+
* CBCore.initIfNeededWithViewCore(new UICore(...))
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* 3. From that point on, every call to `CBCore.sharedInstance` — including
|
|
73
|
+
* calls made internally by the library — returns the MyAppCore instance.
|
|
74
|
+
* Project code should call `MyAppCore.sharedInstance` for the typed version.
|
|
75
|
+
*/
|
|
26
76
|
export class CBCore extends UIObject {
|
|
27
77
|
|
|
28
78
|
private static _sharedInstance: CBCore
|
|
@@ -57,9 +107,6 @@ export class CBCore extends UIObject {
|
|
|
57
107
|
return
|
|
58
108
|
}
|
|
59
109
|
|
|
60
|
-
//console.log("" + event.key + " changed to " + event.newValue + " from " + event.oldValue);
|
|
61
|
-
|
|
62
|
-
|
|
63
110
|
if (event.key == "CBLanguageKey") {
|
|
64
111
|
this.didSetLanguageKey()
|
|
65
112
|
}
|
|
@@ -67,8 +114,6 @@ export class CBCore extends UIObject {
|
|
|
67
114
|
}.bind(this))
|
|
68
115
|
|
|
69
116
|
|
|
70
|
-
//this.checkIfUserIsAuthenticated();
|
|
71
|
-
|
|
72
117
|
this.didSetLanguageKey()
|
|
73
118
|
|
|
74
119
|
|
|
@@ -82,6 +127,15 @@ export class CBCore extends UIObject {
|
|
|
82
127
|
}
|
|
83
128
|
|
|
84
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Returns the shared singleton instance.
|
|
132
|
+
*
|
|
133
|
+
* If `setSharedInstance` was called before this getter was first accessed,
|
|
134
|
+
* that instance is returned. Otherwise a default `CBCore` is created.
|
|
135
|
+
* Library-internal code always goes through this getter, so registering a
|
|
136
|
+
* subclass via `setSharedInstance` is sufficient to replace the singleton
|
|
137
|
+
* for the entire session.
|
|
138
|
+
*/
|
|
85
139
|
static get sharedInstance() {
|
|
86
140
|
if (!CBCore._sharedInstance) {
|
|
87
141
|
CBCore._sharedInstance = new CBCore()
|
|
@@ -90,6 +144,37 @@ export class CBCore extends UIObject {
|
|
|
90
144
|
}
|
|
91
145
|
|
|
92
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Registers a subclass instance as the application singleton.
|
|
149
|
+
*
|
|
150
|
+
* Call this once at app startup, before `CBCore.sharedInstance` or
|
|
151
|
+
* `CBCore.initIfNeededWithViewCore` are first accessed. Calling it after
|
|
152
|
+
* the singleton has already been created has no effect and will throw in
|
|
153
|
+
* development to catch accidental misuse.
|
|
154
|
+
*
|
|
155
|
+
* ```typescript
|
|
156
|
+
* // App entry point — must be the very first thing that runs.
|
|
157
|
+
* CBCore.setSharedInstance(new MyAppCore())
|
|
158
|
+
* CBCore.initIfNeededWithViewCore(new UICore("root", RootViewController))
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
static setSharedInstance(instance: CBCore) {
|
|
162
|
+
|
|
163
|
+
if (CBCore._sharedInstance) {
|
|
164
|
+
/// #if DEV
|
|
165
|
+
throw new Error(
|
|
166
|
+
"CBCore.setSharedInstance must be called before sharedInstance is first accessed. " +
|
|
167
|
+
"Move the call to the very top of your app entry point."
|
|
168
|
+
)
|
|
169
|
+
/// #endif
|
|
170
|
+
return
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
CBCore._sharedInstance = instance
|
|
174
|
+
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
|
|
93
178
|
static broadcastEventName = {
|
|
94
179
|
|
|
95
180
|
"userDidLogIn": "UserDidLogIn",
|
|
@@ -179,6 +264,29 @@ export class CBCore extends UIObject {
|
|
|
179
264
|
this.didSetUserProfile()
|
|
180
265
|
}
|
|
181
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Called whenever `userProfile` is assigned.
|
|
269
|
+
*
|
|
270
|
+
* The default implementation derives `isUserLoggedIn` from the profile
|
|
271
|
+
* and triggers the login/logout broadcast via `didSetIsUserLoggedIn`.
|
|
272
|
+
*
|
|
273
|
+
* Subclasses may override this to fetch additional session data before
|
|
274
|
+
* the broadcast fires. The override must be `async` and must call
|
|
275
|
+
* `super.didSetUserProfile()` after it has finished populating any
|
|
276
|
+
* extra state, so that all broadcast listeners receive a complete core:
|
|
277
|
+
*
|
|
278
|
+
* ```typescript
|
|
279
|
+
* override async didSetUserProfile() {
|
|
280
|
+
* if (IS(this.userProfile)) {
|
|
281
|
+
* this.companyStatus = (await SocketClient.CurrentUserStatusInCompany()).result
|
|
282
|
+
* }
|
|
283
|
+
* else {
|
|
284
|
+
* this.companyStatus = undefined
|
|
285
|
+
* }
|
|
286
|
+
* super.didSetUserProfile() // broadcast fires here
|
|
287
|
+
* }
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
182
290
|
didSetUserProfile() {
|
|
183
291
|
this.isUserLoggedIn = IS(this.userProfile)
|
|
184
292
|
}
|
|
@@ -249,22 +357,3 @@ export class CBCore extends UIObject {
|
|
|
249
357
|
|
|
250
358
|
}
|
|
251
359
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|