@fluid-topics/ft-app-context 1.3.4 → 1.3.6

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.
@@ -2,6 +2,7 @@ import { FtMessageContext, FtMetadataConfiguration, FtSession, FtUiLocale } from
2
2
  export interface FtAppContextProperties {
3
3
  baseUrl?: string;
4
4
  apiIntegrationIdentifier?: string;
5
+ apiIntegrationAppVersion?: string;
5
6
  uiLocale?: string;
6
7
  availableUiLocales?: Array<FtUiLocale>;
7
8
  editorMode?: boolean;
@@ -14,4 +15,5 @@ export interface FtAppContextProperties {
14
15
  openExternalDocumentInNewTab?: boolean;
15
16
  navigatorOnline?: boolean;
16
17
  forcedOffline?: boolean;
18
+ authenticationRequired?: boolean;
17
19
  }
@@ -1,12 +1,14 @@
1
1
  import { FtReduxStore, Optional } from "@fluid-topics/ft-wc-utils";
2
- import { FtDefaultLocales, FtMetadataConfiguration, FtPrivacyPolicyConfiguration, FtSession, FtUiLocale } from "@fluid-topics/public-api";
2
+ import { FtDefaultLocales, FtMetadataConfiguration, FtPrivacyPolicyConfiguration, FtSearchLocale, FtSession, FtUiLocale } from "@fluid-topics/public-api";
3
3
  import { PayloadAction } from "@reduxjs/toolkit";
4
4
  export declare const FtAppInfoStoreName = "ft-app-info";
5
5
  export interface FtAppInfoState {
6
6
  baseUrl: Optional<string>;
7
7
  apiIntegrationIdentifier: Optional<string>;
8
+ apiIntegrationAppVersion: Optional<string>;
8
9
  uiLocale: string;
9
10
  availableUiLocales: Array<FtUiLocale>;
11
+ availableContentLocales: Array<FtSearchLocale>;
10
12
  defaultLocales: FtDefaultLocales | undefined;
11
13
  searchInAllLanguagesAllowed: boolean;
12
14
  metadataConfiguration: Optional<FtMetadataConfiguration>;
@@ -18,6 +20,7 @@ export interface FtAppInfoState {
18
20
  openExternalDocumentInNewTab: boolean;
19
21
  navigatorOnline: boolean;
20
22
  forcedOffline: boolean;
23
+ authenticationRequired: boolean;
21
24
  }
22
25
  export declare class AuthenticationChangeEvent extends CustomEvent<Optional<FtSession>> {
23
26
  static eventName: string;
@@ -21,8 +21,10 @@ export const ftAppInfoStore = FtReduxStore.get({
21
21
  initialState: {
22
22
  baseUrl: undefined,
23
23
  apiIntegrationIdentifier: undefined,
24
+ apiIntegrationAppVersion: undefined,
24
25
  uiLocale: document.documentElement.lang || "en-US",
25
26
  availableUiLocales: [],
27
+ availableContentLocales: [],
26
28
  defaultLocales: undefined,
27
29
  searchInAllLanguagesAllowed: false,
28
30
  metadataConfiguration: undefined,
@@ -34,5 +36,6 @@ export const ftAppInfoStore = FtReduxStore.get({
34
36
  openExternalDocumentInNewTab: false,
35
37
  navigatorOnline: true,
36
38
  forcedOffline: false,
39
+ authenticationRequired: false,
37
40
  },
38
41
  });
@@ -1,10 +1,12 @@
1
- import type { FtDocumentSearchEvent, FtDocumentStartDisplayEvent, FtKhubSearchEvent, FtTopicStartDisplayEvent, FtSearchPageSelectEvent, FtSearchResultOpenContextMenuEvent } from "@fluid-topics/public-api";
2
- import { FtService } from "./FtService";
3
- export declare class FtAnalyticsEventsService extends FtService {
4
- sendDocumentStartDisplayEvent(event: FtDocumentStartDisplayEvent): Promise<void>;
5
- sendTopicStartDisplayEvent(event: FtTopicStartDisplayEvent): Promise<void>;
6
- sendKhubSearchEvent(event: FtKhubSearchEvent): Promise<void>;
7
- sendDocumentSearchEvent(event: FtDocumentSearchEvent): Promise<void>;
8
- sendSearchPageSelectEvent(event: FtSearchPageSelectEvent): Promise<void>;
9
- sendSearchResultOpenContextMenuEvent(event: FtSearchResultOpenContextMenuEvent): Promise<void>;
1
+ import type { FtDocumentSearchEvent, FtDocumentStartDisplayEvent, FtKhubSearchEvent, FtSearchPageSelectEvent, FtSearchResultOpenContextMenuEvent, FtTopicStartDisplayEvent } from "@fluid-topics/public-api";
2
+ import { FtServiceWithCache } from "./FtServiceWithCache";
3
+ export declare class FtAnalyticsEventsService extends FtServiceWithCache {
4
+ sendDocumentStartDisplayEvent(event: FtDocumentStartDisplayEvent): Promise<string>;
5
+ sendTopicStartDisplayEvent(event: FtTopicStartDisplayEvent): Promise<string>;
6
+ sendKhubSearchEvent(event: FtKhubSearchEvent): Promise<string>;
7
+ sendDocumentSearchEvent(event: FtDocumentSearchEvent): Promise<string>;
8
+ sendSearchPageSelectEvent(event: FtSearchPageSelectEvent): Promise<string>;
9
+ sendSearchResultOpenContextMenuEvent(event: FtSearchResultOpenContextMenuEvent): Promise<string>;
10
+ private sortEventArrays;
11
+ private sendEvents;
10
12
  }
@@ -1,51 +1,58 @@
1
- import { FtService } from "./FtService";
2
- export class FtAnalyticsEventsService extends FtService {
1
+ import { FtServiceWithCache } from "./FtServiceWithCache";
2
+ export class FtAnalyticsEventsService extends FtServiceWithCache {
3
3
  async sendDocumentStartDisplayEvent(event) {
4
- return (await this.awaitApi)
5
- .sendEvents([event])
6
- .catch(reason => {
7
- console.info("Failed to send document.start_display event");
8
- console.debug(reason);
9
- });
4
+ return this.sendEvents([this.sortEventArrays(event)], "Failed to send document.start_display event");
10
5
  }
11
6
  async sendTopicStartDisplayEvent(event) {
12
- return (await this.awaitApi)
13
- .sendEvents([event])
14
- .catch(reason => {
15
- console.info("Failed to send topic.start_display event");
16
- console.debug(reason);
17
- });
7
+ return this.sendEvents([this.sortEventArrays(event)], "Failed to send topic.start_display event");
18
8
  }
19
9
  async sendKhubSearchEvent(event) {
20
- return (await this.awaitApi)
21
- .sendEvents([event])
22
- .catch(reason => {
23
- console.info("Failed to send khub.search event");
24
- console.debug(reason);
25
- });
10
+ return this.sendEvents([this.sortEventArrays(event)], "Failed to send khub.search event");
26
11
  }
27
12
  async sendDocumentSearchEvent(event) {
28
- return (await this.awaitApi)
29
- .sendEvents([event])
30
- .catch(reason => {
31
- console.info("Failed to send document.search event");
32
- console.debug(reason);
33
- });
13
+ return this.sendEvents([this.sortEventArrays(event)], "Failed to send document.search event");
34
14
  }
35
15
  async sendSearchPageSelectEvent(event) {
36
- return (await this.awaitApi)
37
- .sendEvents([event])
38
- .catch(reason => {
39
- console.info("Failed to send search_page.select event");
40
- console.debug(reason);
41
- });
16
+ return this.sendEvents([this.sortEventArrays(event)], "Failed to send search_page.select event");
42
17
  }
43
18
  async sendSearchResultOpenContextMenuEvent(event) {
44
- return (await this.awaitApi)
45
- .sendEvents([event])
46
- .catch(reason => {
47
- console.info("Failed to send search_result.open_context_menu event");
48
- console.debug(reason);
19
+ return this.sendEvents([this.sortEventArrays(event)], "Failed to send search_result.open_context_menu event");
20
+ }
21
+ sortEventArrays(object) {
22
+ const entries = Object.entries(object).map(([key, value]) => {
23
+ if (Array.isArray(value)) {
24
+ return [key, value.map((val) => typeof val === 'object' && val != null && !Array.isArray(val) ? this.sortEventArrays(val) : val)
25
+ .sort((a, b) => {
26
+ if (typeof a === 'object' && a !== null && 'key' in a) {
27
+ return a.key.localeCompare(b.key);
28
+ }
29
+ else if (typeof a === 'string' && typeof b === 'string') {
30
+ return a.localeCompare(b);
31
+ }
32
+ else {
33
+ return String(a).localeCompare(String(b));
34
+ }
35
+ })];
36
+ }
37
+ else if (typeof value === 'object' && value !== null) {
38
+ return [key, this.sortEventArrays(value)];
39
+ }
40
+ else {
41
+ return [key, value];
42
+ }
49
43
  });
44
+ return Object.fromEntries(entries);
45
+ }
46
+ sendEvents(events, errorMessage) {
47
+ const fakeResponse = "anything not undefined";
48
+ return this.cache.get("analytics-event-" + this.hash(events), async () => {
49
+ return (await this.awaitApi).sendEvents(events)
50
+ .then(() => fakeResponse)
51
+ .catch(reason => {
52
+ console.info(errorMessage);
53
+ console.debug(reason);
54
+ return fakeResponse;
55
+ });
56
+ }, 1000);
50
57
  }
51
58
  }
@@ -0,0 +1 @@
1
+ export declare function getOrDefaultIfMissingRequiredAuthentication<T>(provider: () => Promise<T>, defaultValue: T): Promise<T>;
@@ -0,0 +1,9 @@
1
+ import { ftAppInfoStore } from "../redux-stores/FtAppInfoStore";
2
+ const store = ftAppInfoStore;
3
+ export function getOrDefaultIfMissingRequiredAuthentication(provider, defaultValue) {
4
+ var _a;
5
+ if (store.getState().authenticationRequired && !((_a = store.getState().session) === null || _a === void 0 ? void 0 : _a.sessionAuthenticated)) {
6
+ return Promise.resolve(defaultValue);
7
+ }
8
+ return provider();
9
+ }
@@ -6,4 +6,6 @@ export declare class FtServiceWithCache extends FtService {
6
6
  cache: CacheRegistry;
7
7
  constructor(withCommonCache?: boolean, overrideApi?: FluidTopicsApi);
8
8
  clearCache(): void;
9
+ private sortObjectFields;
10
+ hash(object: any): string;
9
11
  }
@@ -4,6 +4,13 @@ export class FtServiceWithCache extends FtService {
4
4
  constructor(withCommonCache = true, overrideApi) {
5
5
  var _a;
6
6
  super(overrideApi);
7
+ this.sortObjectFields = (_, value) => {
8
+ if (typeof value !== "object" || value == null || Array.isArray(value)) {
9
+ return value;
10
+ }
11
+ return Object.fromEntries(Object.entries(value)
12
+ .sort(([ka], [kb]) => ka.localeCompare(kb)));
13
+ };
7
14
  // Have a different cache for each child class
8
15
  let constructor = this.constructor;
9
16
  constructor.commonCache = (_a = constructor.commonCache) !== null && _a !== void 0 ? _a : new CacheRegistry();
@@ -12,4 +19,8 @@ export class FtServiceWithCache extends FtService {
12
19
  clearCache() {
13
20
  this.cache.clearAll();
14
21
  }
22
+ hash(object) {
23
+ return String(Array.from(JSON.stringify(object, this.sortObjectFields))
24
+ .reduce((hash, char) => 0 | (31 * hash + char.charCodeAt(0)), 0));
25
+ }
15
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluid-topics/ft-app-context",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
4
4
  "description": "Global application context for Fluid Topics integrations",
5
5
  "keywords": [
6
6
  "Lit"
@@ -19,11 +19,11 @@
19
19
  "url": "ssh://git@scm.mrs.antidot.net:2222/fluidtopics/ft-web-components.git"
20
20
  },
21
21
  "dependencies": {
22
- "@fluid-topics/ft-wc-utils": "1.3.4",
22
+ "@fluid-topics/ft-wc-utils": "1.3.6",
23
23
  "lit": "3.1.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@fluid-topics/public-api": "1.0.99"
27
27
  },
28
- "gitHead": "88282019772befe5149b30c92d1ac38067d25c2b"
28
+ "gitHead": "595e5b638bbf265e174474722661e26767cfbd9d"
29
29
  }