@evoke-platform/context 1.0.0-dev.12 → 1.0.0-dev.121

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.
Files changed (45) hide show
  1. package/README.md +139 -7
  2. package/dist/api/ApiBaseUrlProvider.js +0 -1
  3. package/dist/api/apiServices.js +12 -10
  4. package/dist/api/callback.js +0 -1
  5. package/dist/api/index.js +0 -1
  6. package/dist/api/paramsSerializer.d.ts +2 -0
  7. package/dist/api/paramsSerializer.js +7 -0
  8. package/dist/app/AppProvider.d.ts +12 -1
  9. package/dist/app/AppProvider.js +53 -7
  10. package/dist/app/index.js +0 -1
  11. package/dist/authentication/AuthenticationContextProvider.js +4 -2
  12. package/dist/authentication/index.js +0 -1
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.js +1 -1
  15. package/dist/notification/NotificationProvider.d.ts +33 -0
  16. package/dist/notification/NotificationProvider.js +134 -0
  17. package/dist/notification/index.d.ts +2 -0
  18. package/dist/notification/index.js +2 -0
  19. package/dist/objects/filters.js +0 -1
  20. package/dist/objects/index.js +0 -1
  21. package/dist/objects/objects.d.ts +260 -14
  22. package/dist/objects/objects.js +2 -3
  23. package/dist/router/index.js +0 -1
  24. package/dist/router/navigation.js +0 -1
  25. package/dist/router/routeParams.js +0 -1
  26. package/dist/signalr/SignalRConnectionProvider.js +40 -130
  27. package/dist/signalr/index.js +0 -1
  28. package/package.json +23 -16
  29. package/dist/api/ApiBaseUrlProvider.js.map +0 -1
  30. package/dist/api/apiServices.js.map +0 -1
  31. package/dist/api/callback.js.map +0 -1
  32. package/dist/api/index.js.map +0 -1
  33. package/dist/app/AppProvider.js.map +0 -1
  34. package/dist/app/index.js.map +0 -1
  35. package/dist/authentication/AuthenticationContextProvider.js.map +0 -1
  36. package/dist/authentication/index.js.map +0 -1
  37. package/dist/index.js.map +0 -1
  38. package/dist/objects/filters.js.map +0 -1
  39. package/dist/objects/index.js.map +0 -1
  40. package/dist/objects/objects.js.map +0 -1
  41. package/dist/router/index.js.map +0 -1
  42. package/dist/router/navigation.js.map +0 -1
  43. package/dist/router/routeParams.js.map +0 -1
  44. package/dist/signalr/SignalRConnectionProvider.js.map +0 -1
  45. package/dist/signalr/index.js.map +0 -1
package/README.md CHANGED
@@ -17,7 +17,7 @@ available and no further installation is necessary.
17
17
 
18
18
  - [Working With Objects](#working-with-objects)
19
19
  - [REST API Calls](#rest-api-calls)
20
- - [SignalR Connection](#signalr-connection)
20
+ - [Notifications](#notifications)
21
21
 
22
22
  ### Working With Objects
23
23
 
@@ -68,7 +68,8 @@ const results = await applications.findInstances();
68
68
 
69
69
  ##### `get(options)`
70
70
 
71
- Get the object definition for this store's object.
71
+ Get the object definition for this store's object. The returned object includes inherited properties and actions if
72
+ this object is derived from another object.
72
73
 
73
74
  - `options` _[object]_ - _optional_
74
75
  - `sanitized` _[boolean]_
@@ -159,7 +160,16 @@ Returns a function that can be used to navigate to another page. The returned fu
159
160
 
160
161
  #### `useApp()`
161
162
 
162
- Returns the currently loaded Evoke app.
163
+ Returns the currently loaded Evoke App as well as the following function.
164
+
165
+ - `findDefaultPageSlugFor`: An asynchronous function that takes an `objectId` as a parameter and returns the default page slug for that object, if no default page slug is found and the object is a subtype, the page slug of the first ancestor with a default page will be used. It returns `undefined` if no default page slug is found for any ancestor type.
166
+
167
+ Example usage:
168
+
169
+ ```javascript
170
+ const { id: appId, findDefaultPageSlugFor } = useApp();
171
+ const defaultPageSlug = await findDefaultPageSlugFor(objectId);
172
+ ```
163
173
 
164
174
  ### REST API calls
165
175
 
@@ -196,18 +206,117 @@ absolute URL.
196
206
 
197
207
  ##### `delete(url, options)`
198
208
 
199
- ### SignalR Connection
209
+ ### Notifications
210
+
211
+ - [useNofitication](#usenotification)
212
+ - [documentChanges](#documentchangessubscribeobjectidinstanceid-data-documentchange)
213
+ - [instanceChanges](#instancechangessubscribeobjectid-instanceids-instancechange)
214
+ - [useSignalRConnection](#usesignalrconnection) (_Deprecated_)
215
+ - [documentChanges](#documentchangessubscribeobjectidinstanceid-data-documentchange) (_Deprecated_)
216
+ - [instanceChanges](#instancechangessubscribeobjectid-instanceids-instancechange) (_Deprecated_)
217
+
218
+ #### `useNofitication()`
219
+
220
+ Hook used to obtain an instanceChanges instance and a documentChanges instance.
221
+
222
+ ##### `documentChanges.subscribe(objectId, instanceId, (data: DocumentChange[]]) => {})`
223
+
224
+ Subscribe to the specified object instance changes.
225
+
226
+ ```javascript
227
+ const { documentChanges } = useNotification();
228
+
229
+ documentChanges.subscribe('myObjectId', 'myInstanceId', (data) => {
230
+ console.log(data);
231
+ });
232
+ ```
233
+
234
+ The data provided to the callback will be an array of `DocumentChange` which contains the
235
+ following data:
236
+
237
+ - `objectId`
238
+ - Object describing the instance associated with the updated document.
239
+ - `instanceId`
240
+ - Instance that the updated document is associated with.
241
+ - `documentId`
242
+ - Document that was updated.
243
+ - `type`
244
+ - The type of update. Possible values are `BlobCreated`, `BlobDeleted`, and `BlobMetadataUpdated`.
245
+
246
+ ##### `documentChanges.unsubscribe(objectId, instanceId, (changes: DocumentChange[]) => {})`
247
+
248
+ Unsubscribe to the specified object instance changes.
249
+
250
+ Callback function is optional.
251
+ If callback function is not defined, all subscriptions will be removed.
252
+ If callback function is defined, you must pass the exact same Function instance as was previously passed to `documentChanges.subscribe`.
253
+ Passing a different instance (even if the function body is the same) will not remove the subscription.
254
+
255
+ ```javascript
256
+ const { documentChanges } = useNotification();
257
+
258
+ const callback = (changes: DocumentChange[]) => {
259
+ console.log(changes);
260
+ };
261
+
262
+ documentChanges.subscribe('myObjectId', 'myInstanceId', callback);
263
+
264
+ documentChanges.unsubscribe('myObjectId', 'myInstanceId', callback);
265
+ ```
266
+
267
+ ##### `instanceChanges.subscribe(objectId, (changes: InstanceChange[]) => {})`
268
+
269
+ Subscribe to the specified object changes.
270
+
271
+ ```javascript
272
+ const { instanceChanges } = useNotification();
273
+
274
+ instanceChanges.subscribe('myObjectId', (changes) => {
275
+ console.log(changes);
276
+ });
277
+ ```
278
+
279
+ The data provided to the callback will be an array of `InstanceChange` which contains the
280
+ following data:
281
+
282
+ - `objectId`
283
+ - Object describing the instance associated with the updated document.
284
+ - `instanceId`
285
+ - Instance that the updated document is associated with.
286
+
287
+ ##### `instanceChanges.unsubscribe(objectId, (changes: InstanceChange[]) => {})`
288
+
289
+ Unsubscribe to the specified object changes.
290
+
291
+ Callback function is optional.
292
+ If callback function is not defined, all subscriptions will be removed.
293
+ If callback function is defined, you must pass the exact same Function instance as was previously passed to `instanceChanges.subscribe`.
294
+ Passing a different instance (even if the function body is the same) will not remove the subscription.
200
295
 
201
- - [useSignalRConnection](#usesignalrconnection)
202
- - [documentChanges](#documentchanges)
203
- - [instanceChanges](#instancechanges)
296
+ ```javascript
297
+ const { instanceChanges } = useNotification();
298
+
299
+ const callback = (changes: InstanceChange[]) => {
300
+ console.log(changes);
301
+ };
302
+
303
+ instanceChanges.subscribe('myObjectId', callback);
304
+
305
+ instanceChanges.unsubscribe('myObjectId', callback);
306
+ ```
204
307
 
205
308
  #### `useSignalRConnection()`
206
309
 
310
+ > **Deprecated**
311
+ > This has been deprecated in favor of [useNotification](#usenofitication).
312
+
207
313
  Hook used to obtain an instanceChanges instance of `SignalRConnection` and a documentChanges instance of `SignalRConnection`.
208
314
 
209
315
  ##### `documentChanges.subscribe('{objectId}/{instanceId}', (data: DocumentChange[]]) => {})`
210
316
 
317
+ > **Deprecated**
318
+ > This has been deprecated in favor of [useNotification](#usenofitication).
319
+
211
320
  Subscribe to the specified object instance document changes.
212
321
 
213
322
  ```javascript
@@ -218,8 +327,23 @@ documentChanges.subscribe('myObjectId/myInstanceId', (data) => {
218
327
  });
219
328
  ```
220
329
 
330
+ The data provided to the callback will be an array of `DocumentChange` which contains the
331
+ following data:
332
+
333
+ - `objectId`
334
+ - Object describing the instance associated with the updated document.
335
+ - `instanceId`
336
+ - Instance that the updated document is associated with.
337
+ - `documentId`
338
+ - Document that was updated.
339
+ - `type`
340
+ - The type of update. Possible values are `BlobCreated`, `BlobDeleted`, and `BlobMetadataUpdated`.
341
+
221
342
  ##### `documentChanges.unsubscribe('{objectId}/{instanceId}', (data: DocumentChange[]) => {})`
222
343
 
344
+ > **Deprecated**
345
+ > This has been deprecated in favor of [useNotification](#usenofitication).
346
+
223
347
  Unsubscribe to the specified object instance document changes.
224
348
 
225
349
  Callback function is optional.
@@ -240,6 +364,9 @@ documentChanges.unsubscribe('myObjectId/myInstanceId', callback);
240
364
 
241
365
  ##### `instanceChanges.subscribe('{objectId}', (instanceIds: InstanceChange[]) => {})`
242
366
 
367
+ > **Deprecated**
368
+ > This has been deprecated in favor of [useNotification](#usenofitication).
369
+
243
370
  Subscribe to the specified object instance changes.
244
371
 
245
372
  ```javascript
@@ -250,8 +377,13 @@ instanceChanges.subscribe('myObjectId', (instanceIds) => {
250
377
  });
251
378
  ```
252
379
 
380
+ The data provided to the callback will be an array of instance IDs that were updated.
381
+
253
382
  ##### `instanceChanges.unsubscribe('{objectId}', (instanceIds: InstanceChange[]) => {})`
254
383
 
384
+ > **Deprecated**
385
+ > This has been deprecated in favor of [useNotification](#usenofitication).
386
+
255
387
  Unsubscribe to the specified object instance changes.
256
388
 
257
389
  Callback function is optional.
@@ -13,4 +13,3 @@ export function useApiBaseUrl() {
13
13
  return useContext(ApiBaseUrlContext);
14
14
  }
15
15
  export default ApiBaseUrlProvider;
16
- //# sourceMappingURL=ApiBaseUrlProvider.js.map
@@ -11,20 +11,23 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  };
12
12
  import axios from 'axios';
13
13
  import { useMemo } from 'react';
14
+ import { v4 as uuidv4 } from 'uuid';
14
15
  import { useAuthenticationContext } from '../authentication/AuthenticationContextProvider.js';
15
16
  import { useApiBaseUrl } from './ApiBaseUrlProvider.js';
17
+ import { paramsSerializer } from './paramsSerializer.js';
18
+ const sessionId = uuidv4();
16
19
  export class ApiServices {
17
20
  constructor(api, authContext) {
18
21
  this.api = api;
19
- if (authContext) {
20
- this.api.interceptors.request.use((config) => __awaiter(this, void 0, void 0, function* () {
22
+ this.api.interceptors.request.use((config) => __awaiter(this, void 0, void 0, function* () {
23
+ const headers = { 'X-Session-Id': sessionId };
24
+ if (authContext) {
21
25
  const token = yield authContext.getAccessToken();
22
- config.headers = Object.assign({}, config.headers, {
23
- Authorization: `Bearer ${token}`,
24
- });
25
- return config;
26
- }));
27
- }
26
+ headers['Authorization'] = `Bearer ${token}`;
27
+ }
28
+ config.headers = Object.assign({}, config.headers, headers);
29
+ return config;
30
+ }));
28
31
  }
29
32
  promiseOrCallback(promise, cb) {
30
33
  return __awaiter(this, void 0, void 0, function* () {
@@ -141,7 +144,6 @@ export class ApiServices {
141
144
  export function useApiServices() {
142
145
  const authContext = useAuthenticationContext();
143
146
  const baseURL = useApiBaseUrl();
144
- const apiServices = useMemo(() => new ApiServices(axios.create({ baseURL }), authContext), [authContext, baseURL]);
147
+ const apiServices = useMemo(() => new ApiServices(axios.create({ baseURL, paramsSerializer }), authContext), [authContext, baseURL]);
145
148
  return apiServices;
146
149
  }
147
- //# sourceMappingURL=apiServices.js.map
@@ -10,4 +10,3 @@ export function callback(onSuccess, onError) {
10
10
  }
11
11
  };
12
12
  }
13
- //# sourceMappingURL=callback.js.map
package/dist/api/index.js CHANGED
@@ -4,4 +4,3 @@ export * from './ApiBaseUrlProvider.js';
4
4
  export { default as ApiBaseUrlProvider } from './ApiBaseUrlProvider.js';
5
5
  export * from './apiServices.js';
6
6
  export * from './callback.js';
7
- //# sourceMappingURL=index.js.map
@@ -0,0 +1,2 @@
1
+ import { ParamsSerializerOptions } from 'axios';
2
+ export declare function paramsSerializer(params: Record<string, unknown>, options?: ParamsSerializerOptions): string;
@@ -0,0 +1,7 @@
1
+ export function paramsSerializer(params, options) {
2
+ const searchParams = new URLSearchParams();
3
+ for (const [key, value] of Object.entries(params)) {
4
+ searchParams.append(key, typeof value !== 'string' ? JSON.stringify(value) : value);
5
+ }
6
+ return searchParams.toString();
7
+ }
@@ -10,10 +10,12 @@ export type App = {
10
10
  iconColor?: string;
11
11
  pages?: Page[];
12
12
  navigation?: NavigationMenu;
13
+ defaultPages?: Record<string, string>;
13
14
  };
14
15
  export type Page = {
15
16
  id: string;
16
17
  name: string;
18
+ slug?: string;
17
19
  children?: PageElement[];
18
20
  };
19
21
  export type PageElement = Container | Widget;
@@ -36,10 +38,19 @@ export type NavigationItem = {
36
38
  pageId: string;
37
39
  pageName: string;
38
40
  };
41
+ export type AppExtended = App & {
42
+ /**
43
+ * Looks up the default page slug for a given object or its nearest type ancestor.
44
+ *
45
+ * @param {string} objectId - The ID of the object to start the search from.
46
+ * @returns {Promise<string | undefined>} The default page slug, or `undefined` if no default page is found.
47
+ */
48
+ findDefaultPageSlugFor: (objectId: string) => Promise<string | undefined>;
49
+ };
39
50
  export type AppProviderProps = {
40
51
  app: App;
41
52
  children?: ReactNode;
42
53
  };
43
54
  declare function AppProvider(props: AppProviderProps): import("react/jsx-runtime").JSX.Element;
44
- export declare function useApp(): App;
55
+ export declare function useApp(): AppExtended;
45
56
  export default AppProvider;
@@ -1,16 +1,62 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import { jsx as _jsx } from "react/jsx-runtime";
2
- // Copyright (c) 2023 System Automation Corporation.
3
- // This file is licensed under the MIT License.
4
- import { createContext, useContext } from 'react';
5
- const defaultApp = { id: '_evoke', name: 'Evoke Platform', type: 'public' };
6
- const AppContext = createContext(defaultApp);
11
+ import { createContext, useCallback, useContext } from 'react';
12
+ import { useApiServices } from '../api/index.js';
13
+ const defaultApp = {
14
+ id: '_evoke',
15
+ name: 'Evoke Platform',
16
+ type: 'public',
17
+ };
18
+ const defaultAppExtended = Object.assign(Object.assign({}, defaultApp), { findDefaultPageSlugFor: (objectId) => Promise.resolve(undefined) });
19
+ const AppContext = createContext(defaultAppExtended);
7
20
  AppContext.displayName = 'AppContext';
8
21
  function AppProvider(props) {
9
22
  const { app, children } = props;
10
- return _jsx(AppContext.Provider, { value: app, children: children });
23
+ const apiServices = useApiServices();
24
+ const appExtended = Object.assign(Object.assign({}, app), { findDefaultPageSlugFor: useCallback((objectId) => __awaiter(this, void 0, void 0, function* () {
25
+ var _a, _b, _c, _d;
26
+ let defaultPageId;
27
+ let currentObjectId = objectId;
28
+ while (currentObjectId !== undefined) {
29
+ if ((_a = app.defaultPages) === null || _a === void 0 ? void 0 : _a[currentObjectId]) {
30
+ defaultPageId = app.defaultPages[currentObjectId];
31
+ break;
32
+ }
33
+ const effectiveObject = yield apiServices.get(`data/objects/${currentObjectId}/effective`, {
34
+ params: { filter: { fields: ['baseObject'] } },
35
+ });
36
+ currentObjectId = (_c = (_b = effectiveObject === null || effectiveObject === void 0 ? void 0 : effectiveObject.baseObject) === null || _b === void 0 ? void 0 : _b.objectId) !== null && _c !== void 0 ? _c : undefined;
37
+ }
38
+ let defaultPage;
39
+ if (defaultPageId) {
40
+ const pageId = defaultPageId.includes('/')
41
+ ? defaultPageId.split('/').slice(2).join('/')
42
+ : defaultPageId;
43
+ try {
44
+ defaultPage = yield apiServices.get(`/webContent/apps/${app.id}/pages/${encodeURIComponent(encodeURIComponent(pageId))}`);
45
+ }
46
+ catch (error) {
47
+ const err = error;
48
+ if (((_d = err.response) === null || _d === void 0 ? void 0 : _d.status) === 404) {
49
+ defaultPage = undefined;
50
+ }
51
+ }
52
+ }
53
+ if (defaultPage === null || defaultPage === void 0 ? void 0 : defaultPage.slug) {
54
+ return `/${app.id}/${defaultPage.slug}`;
55
+ }
56
+ }), [app]) });
57
+ return _jsx(AppContext.Provider, { value: appExtended, children: children });
11
58
  }
12
59
  export function useApp() {
13
60
  return useContext(AppContext);
14
61
  }
15
62
  export default AppProvider;
16
- //# sourceMappingURL=AppProvider.js.map
package/dist/app/index.js CHANGED
@@ -2,4 +2,3 @@
2
2
  // This file is licensed under the MIT License.
3
3
  export * from './AppProvider.js';
4
4
  export { default as AppProvider } from './AppProvider.js';
5
- //# sourceMappingURL=index.js.map
@@ -31,7 +31,10 @@ function AuthenticationContextProvider(props) {
31
31
  ? {
32
32
  account: { id: account.localAccountId, name: account.name },
33
33
  logout: () => {
34
- msal.instance.logoutRedirect({ account });
34
+ msal.instance.logoutRedirect({
35
+ account,
36
+ postLogoutRedirectUri: `/logout?p=${encodeURIComponent(window.location.pathname + window.location.search)}`,
37
+ });
35
38
  },
36
39
  getAccessToken,
37
40
  }
@@ -42,4 +45,3 @@ export function useAuthenticationContext() {
42
45
  return useContext(Context);
43
46
  }
44
47
  export default AuthenticationContextProvider;
45
- //# sourceMappingURL=AuthenticationContextProvider.js.map
@@ -2,4 +2,3 @@
2
2
  // This file is licensed under the MIT License.
3
3
  export * from './AuthenticationContextProvider.js';
4
4
  export { default as AuthenticationContextProvider } from './AuthenticationContextProvider.js';
5
- //# sourceMappingURL=index.js.map
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './api/index.js';
2
2
  export * from './app/index.js';
3
3
  export * from './authentication/index.js';
4
+ export * from './notification/index.js';
4
5
  export * from './objects/index.js';
5
6
  export * from './router/index.js';
6
7
  export * from './signalr/index.js';
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  export * from './api/index.js';
4
4
  export * from './app/index.js';
5
5
  export * from './authentication/index.js';
6
+ export * from './notification/index.js';
6
7
  export * from './objects/index.js';
7
8
  export * from './router/index.js';
8
9
  export * from './signalr/index.js';
9
- //# sourceMappingURL=index.js.map
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ export type NotificationConnectionInfo = {
3
+ url: string;
4
+ accessToken: string;
5
+ };
6
+ export type InstanceSubscription = {
7
+ subscribe: (objectId: string, callback: (...args: NotificationInstanceChange[]) => void) => void;
8
+ unsubscribe: (objectId: string, callback?: (...args: NotificationInstanceChange[]) => void) => void;
9
+ };
10
+ export type DocumentSubscription = {
11
+ subscribe: (objectId: string, instanceId: string | undefined, callback: (...args: NotificationDocumentChange[]) => void) => void;
12
+ unsubscribe: (objectId: string, instanceId: string | undefined, callback?: (...args: NotificationDocumentChange[]) => void) => void;
13
+ };
14
+ export type NotificationDocumentChange = {
15
+ objectId: string;
16
+ instanceId: string;
17
+ documentId: string;
18
+ type: string;
19
+ };
20
+ export type NotificationInstanceChange = {
21
+ objectId: string;
22
+ instanceId: string;
23
+ };
24
+ export type NotificationContextType = {
25
+ documentChanges?: DocumentSubscription;
26
+ instanceChanges?: InstanceSubscription;
27
+ };
28
+ export declare const NotificationContext: React.Context<NotificationContextType>;
29
+ declare function NotificationProvider({ children }: {
30
+ children: React.ReactNode;
31
+ }): import("react/jsx-runtime").JSX.Element;
32
+ export declare function useNotification(): NotificationContextType;
33
+ export default NotificationProvider;
@@ -0,0 +1,134 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ import { HubConnectionBuilder, LogLevel, } from '@microsoft/signalr';
12
+ import { createContext, useContext, useEffect, useState } from 'react';
13
+ import { useApiServices } from '../api/index.js';
14
+ export const NotificationContext = createContext({});
15
+ NotificationContext.displayName = 'NotificationContext';
16
+ function NotificationProvider({ children }) {
17
+ const [instancesNotification, setInstancesNotification] = useState();
18
+ const [documentsNotification, setDocumentsNotification] = useState();
19
+ const api = useApiServices();
20
+ useEffect(() => {
21
+ const getConnectionInfo = (hubName) => {
22
+ return api.post(`/notification/hubs/${hubName}/negotiate`);
23
+ };
24
+ const getConnection = () => __awaiter(this, void 0, void 0, function* () {
25
+ try {
26
+ const instancesConnectionInfo = yield getConnectionInfo('instanceChanges');
27
+ const documentsConnectionInfo = yield getConnectionInfo('documentChanges');
28
+ if (instancesConnectionInfo) {
29
+ const options = {
30
+ accessTokenFactory: () => {
31
+ var _a;
32
+ return (_a = instancesConnectionInfo.accessToken) !== null && _a !== void 0 ? _a : '';
33
+ },
34
+ };
35
+ const connection = new HubConnectionBuilder()
36
+ .withUrl(instancesConnectionInfo.url, options)
37
+ .configureLogging(LogLevel.Error)
38
+ .withAutomaticReconnect()
39
+ .build();
40
+ setInstancesNotification(connection);
41
+ }
42
+ if (documentsConnectionInfo) {
43
+ const options = {
44
+ accessTokenFactory: () => {
45
+ var _a;
46
+ return (_a = documentsConnectionInfo.accessToken) !== null && _a !== void 0 ? _a : '';
47
+ },
48
+ };
49
+ const connection = new HubConnectionBuilder()
50
+ .withUrl(documentsConnectionInfo.url, options)
51
+ .configureLogging(LogLevel.Error)
52
+ .withAutomaticReconnect()
53
+ .build();
54
+ setDocumentsNotification(connection);
55
+ }
56
+ // eslint-disable-next-line no-empty
57
+ }
58
+ catch (err) {
59
+ console.log(err);
60
+ }
61
+ });
62
+ getConnection();
63
+ }, []);
64
+ useEffect(() => {
65
+ let documentsConnectionStopped = false;
66
+ const startConnection = (connection, numOfAttempts) => __awaiter(this, void 0, void 0, function* () {
67
+ yield connection.start().catch((error) => {
68
+ if (numOfAttempts < 4 && !documentsConnectionStopped) {
69
+ setTimeout(() => {
70
+ if (!documentsConnectionStopped) {
71
+ startConnection(connection, numOfAttempts + 1);
72
+ }
73
+ }, 2000);
74
+ }
75
+ else {
76
+ console.warn(`Cannot start connection to Notification Service due to error "${error}"`);
77
+ }
78
+ });
79
+ });
80
+ if (documentsNotification) {
81
+ startConnection(documentsNotification, 0);
82
+ }
83
+ return () => {
84
+ documentsNotification === null || documentsNotification === void 0 ? void 0 : documentsNotification.stop();
85
+ documentsConnectionStopped = true;
86
+ };
87
+ }, [documentsNotification]);
88
+ useEffect(() => {
89
+ let instancesConnectionStopped = false;
90
+ const startConnection = (connection, numOfAttempts) => __awaiter(this, void 0, void 0, function* () {
91
+ yield connection.start().catch((error) => {
92
+ if (numOfAttempts < 4 && !instancesConnectionStopped) {
93
+ setTimeout(() => {
94
+ if (!instancesConnectionStopped) {
95
+ startConnection(connection, numOfAttempts + 1);
96
+ }
97
+ }, 2000);
98
+ }
99
+ else {
100
+ console.warn(`Cannot start connection to Notification Service due to error "${error}"`);
101
+ }
102
+ });
103
+ });
104
+ if (instancesNotification) {
105
+ startConnection(instancesNotification, 0);
106
+ }
107
+ return () => {
108
+ instancesNotification === null || instancesNotification === void 0 ? void 0 : instancesNotification.stop();
109
+ instancesConnectionStopped = true;
110
+ };
111
+ }, [instancesNotification]);
112
+ return (_jsx(NotificationContext.Provider, { value: {
113
+ documentChanges: documentsNotification
114
+ ? {
115
+ subscribe: (objectId, instanceId, callback) => documentsNotification.on(`${objectId}/${instanceId}`, callback),
116
+ unsubscribe: (objectId, instanceId, callback) => callback
117
+ ? documentsNotification.off(`${objectId}/${instanceId}`, callback)
118
+ : documentsNotification.off(`${objectId}/${instanceId}`),
119
+ }
120
+ : undefined,
121
+ instanceChanges: instancesNotification
122
+ ? {
123
+ subscribe: (objectId, callback) => instancesNotification.on(objectId, callback),
124
+ unsubscribe: (objectId, callback) => callback
125
+ ? instancesNotification.off(objectId, callback)
126
+ : instancesNotification.off(objectId),
127
+ }
128
+ : undefined,
129
+ }, children: children }));
130
+ }
131
+ export function useNotification() {
132
+ return useContext(NotificationContext);
133
+ }
134
+ export default NotificationProvider;
@@ -0,0 +1,2 @@
1
+ export * from './NotificationProvider.js';
2
+ export { default as NotificationProvider } from './NotificationProvider.js';
@@ -0,0 +1,2 @@
1
+ export * from './NotificationProvider.js';
2
+ export { default as NotificationProvider } from './NotificationProvider.js';
@@ -1,4 +1,3 @@
1
1
  // Copyright (c) 2023 System Automation Corporation.
2
2
  // This file is licensed under the MIT License.
3
3
  export {};
4
- //# sourceMappingURL=filters.js.map
@@ -2,4 +2,3 @@
2
2
  // This file is licensed under the MIT License.
3
3
  export * from './filters.js';
4
4
  export * from './objects.js';
5
- //# sourceMappingURL=index.js.map