@equinor/fusion-framework-module-bookmark 4.0.2 → 4.0.4
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/CHANGELOG.md +19 -0
- package/dist/esm/BookmarkClient.js +18 -3
- package/dist/esm/BookmarkClient.js.map +1 -1
- package/dist/esm/{BookmarkProvider.error.js → BookmarkFlowError.js} +9 -7
- package/dist/esm/BookmarkFlowError.js.map +1 -0
- package/dist/esm/{BookmarkConfigurator.js → BookmarkModuleConfigurator.js} +38 -6
- package/dist/esm/BookmarkModuleConfigurator.js.map +1 -0
- package/dist/esm/BookmarkProvider.js +112 -23
- package/dist/esm/BookmarkProvider.js.map +1 -1
- package/dist/esm/BookmarkProvider.selectors.js +8 -0
- package/dist/esm/BookmarkProvider.selectors.js.map +1 -1
- package/dist/esm/BookmarkProviderError.js +20 -0
- package/dist/esm/BookmarkProviderError.js.map +1 -0
- package/dist/esm/{BookmarkProvider.actions.js → bookmark-actions.js} +1 -1
- package/dist/esm/bookmark-actions.js.map +1 -0
- package/dist/esm/bookmark-config.schema.js +2 -0
- package/dist/esm/bookmark-config.schema.js.map +1 -1
- package/dist/esm/bookmark-flows/bookmark-api-flows.js +28 -0
- package/dist/esm/bookmark-flows/bookmark-api-flows.js.map +1 -0
- package/dist/esm/bookmark-flows/handle-add-bookmark-as-favorite.js +27 -0
- package/dist/esm/bookmark-flows/handle-add-bookmark-as-favorite.js.map +1 -0
- package/dist/esm/bookmark-flows/handle-create-bookmark.js +27 -0
- package/dist/esm/bookmark-flows/handle-create-bookmark.js.map +1 -0
- package/dist/esm/bookmark-flows/handle-delete-bookmark.js +26 -0
- package/dist/esm/bookmark-flows/handle-delete-bookmark.js.map +1 -0
- package/dist/esm/bookmark-flows/handle-fetch-all-bookmark.js +29 -0
- package/dist/esm/bookmark-flows/handle-fetch-all-bookmark.js.map +1 -0
- package/dist/esm/bookmark-flows/handle-fetch-bookmark-data.js +26 -0
- package/dist/esm/bookmark-flows/handle-fetch-bookmark-data.js.map +1 -0
- package/dist/esm/bookmark-flows/handle-fetch-bookmark.js +30 -0
- package/dist/esm/bookmark-flows/handle-fetch-bookmark.js.map +1 -0
- package/dist/esm/bookmark-flows/handle-remove-bookmark-from-favorites.js +28 -0
- package/dist/esm/bookmark-flows/handle-remove-bookmark-from-favorites.js.map +1 -0
- package/dist/esm/bookmark-flows/handle-remove-bookmark.js +49 -0
- package/dist/esm/bookmark-flows/handle-remove-bookmark.js.map +1 -0
- package/dist/esm/bookmark-flows/handle-update-bookmark.js +28 -0
- package/dist/esm/bookmark-flows/handle-update-bookmark.js.map +1 -0
- package/dist/esm/bookmark-flows/index.js +11 -0
- package/dist/esm/bookmark-flows/index.js.map +1 -0
- package/dist/esm/bookmark-module.js +2 -2
- package/dist/esm/bookmark-module.js.map +1 -1
- package/dist/esm/bookmark.schemas.js +9 -3
- package/dist/esm/bookmark.schemas.js.map +1 -1
- package/dist/esm/create-bookmark-reducer.js +122 -0
- package/dist/esm/create-bookmark-reducer.js.map +1 -0
- package/dist/esm/{BookmarkProvider.store.js → create-bookmark-store.js} +3 -3
- package/dist/esm/create-bookmark-store.js.map +1 -0
- package/dist/esm/enable-bookmark.js +2 -1
- package/dist/esm/enable-bookmark.js.map +1 -1
- package/dist/esm/index.js +12 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/BookmarkClient.d.ts +1 -0
- package/dist/types/{BookmarkProvider.error.d.ts → BookmarkFlowError.d.ts} +9 -4
- package/dist/types/{BookmarkConfigurator.d.ts → BookmarkModuleConfigurator.d.ts} +10 -4
- package/dist/types/BookmarkProvider.d.ts +81 -18
- package/dist/types/BookmarkProvider.interface.d.ts +1 -1
- package/dist/types/BookmarkProvider.selectors.d.ts +3 -3
- package/dist/types/BookmarkProviderError.d.ts +16 -0
- package/dist/types/{BookmarkProvider.actions.d.ts → bookmark-actions.d.ts} +3 -3
- package/dist/types/bookmark-flows/bookmark-api-flows.d.ts +11 -0
- package/dist/types/bookmark-flows/handle-add-bookmark-as-favorite.d.ts +10 -0
- package/dist/types/bookmark-flows/handle-create-bookmark.d.ts +10 -0
- package/dist/types/bookmark-flows/handle-delete-bookmark.d.ts +10 -0
- package/dist/types/bookmark-flows/handle-fetch-all-bookmark.d.ts +10 -0
- package/dist/types/bookmark-flows/handle-fetch-bookmark-data.d.ts +10 -0
- package/dist/types/bookmark-flows/handle-fetch-bookmark.d.ts +10 -0
- package/dist/types/bookmark-flows/handle-remove-bookmark-from-favorites.d.ts +10 -0
- package/dist/types/bookmark-flows/handle-remove-bookmark.d.ts +14 -0
- package/dist/types/bookmark-flows/handle-update-bookmark.d.ts +10 -0
- package/dist/types/bookmark-flows/index.d.ts +10 -0
- package/dist/types/bookmark-module.d.ts +1 -1
- package/dist/types/{BookmarkProvider.reducer.d.ts → create-bookmark-reducer.d.ts} +39 -39
- package/dist/types/{BookmarkProvider.store.d.ts → create-bookmark-store.d.ts} +2 -2
- package/dist/types/enable-bookmark.d.ts +1 -1
- package/dist/types/index.d.ts +12 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +11 -11
- package/src/BookmarkClient.ts +21 -3
- package/src/{BookmarkProvider.error.ts → BookmarkFlowError.ts} +9 -7
- package/src/{BookmarkConfigurator.ts → BookmarkModuleConfigurator.ts} +42 -12
- package/src/BookmarkProvider.interface.ts +3 -2
- package/src/BookmarkProvider.selectors.ts +10 -2
- package/src/BookmarkProvider.ts +112 -23
- package/src/BookmarkProviderError.ts +19 -0
- package/src/{BookmarkProvider.actions.ts → bookmark-actions.ts} +1 -1
- package/src/bookmark-config.schema.ts +2 -0
- package/src/bookmark-flows/bookmark-api-flows.ts +45 -0
- package/src/bookmark-flows/handle-add-bookmark-as-favorite.ts +49 -0
- package/src/bookmark-flows/handle-create-bookmark.ts +47 -0
- package/src/bookmark-flows/handle-delete-bookmark.ts +47 -0
- package/src/bookmark-flows/handle-fetch-all-bookmark.ts +53 -0
- package/src/bookmark-flows/handle-fetch-bookmark-data.ts +58 -0
- package/src/bookmark-flows/handle-fetch-bookmark.ts +64 -0
- package/src/bookmark-flows/handle-remove-bookmark-from-favorites.ts +49 -0
- package/src/bookmark-flows/handle-remove-bookmark.ts +76 -0
- package/src/bookmark-flows/handle-update-bookmark.ts +48 -0
- package/src/bookmark-flows/index.ts +10 -0
- package/src/bookmark-module.ts +2 -2
- package/src/bookmark.schemas.ts +10 -4
- package/src/create-bookmark-reducer.ts +149 -0
- package/src/{BookmarkProvider.store.ts → create-bookmark-store.ts} +4 -4
- package/src/enable-bookmark.ts +3 -2
- package/src/index.ts +12 -1
- package/src/version.ts +1 -1
- package/dist/esm/BookmarkConfigurator.js.map +0 -1
- package/dist/esm/BookmarkProvider.actions.js.map +0 -1
- package/dist/esm/BookmarkProvider.error.js.map +0 -1
- package/dist/esm/BookmarkProvider.flows.js +0 -217
- package/dist/esm/BookmarkProvider.flows.js.map +0 -1
- package/dist/esm/BookmarkProvider.reducer.js +0 -113
- package/dist/esm/BookmarkProvider.reducer.js.map +0 -1
- package/dist/esm/BookmarkProvider.store.js.map +0 -1
- package/dist/types/BookmarkProvider.flows.d.ts +0 -79
- package/src/BookmarkProvider.flows.ts +0 -421
- package/src/BookmarkProvider.reducer.ts +0 -144
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { BookmarkState } from './
|
|
2
|
-
import type { BookmarkFlowError } from './
|
|
1
|
+
import type { BookmarkState } from './create-bookmark-store';
|
|
2
|
+
import type { BookmarkFlowError } from './BookmarkFlowError';
|
|
3
3
|
import type { BookmarkWithoutData } from './types';
|
|
4
4
|
/**
|
|
5
5
|
* Creates a reducer for managing the state of bookmarks.
|
|
6
6
|
*
|
|
7
|
-
* @todo add fast-deep-equal to compare bookmarks
|
|
7
|
+
* @todo TODO(#5135) - add fast-deep-equal to compare bookmarks
|
|
8
8
|
*
|
|
9
9
|
* @param initialState - The initial state of the bookmarks.
|
|
10
10
|
* @returns A reducer function for managing the bookmarks state.
|
|
@@ -18,67 +18,67 @@ export declare const createBookmarkReducer: (initialState?: Partial<BookmarkStat
|
|
|
18
18
|
} | {
|
|
19
19
|
payload: import("./types").Bookmark<any> | null;
|
|
20
20
|
type: "set_current_bookmark";
|
|
21
|
-
} | import("@equinor/fusion-observable").PayloadAction<string, "
|
|
21
|
+
} | import("@equinor/fusion-observable").PayloadAction<string, "add_favourite_bookmark::request", {
|
|
22
22
|
ref: string;
|
|
23
|
-
}
|
|
24
|
-
ref: string;
|
|
25
|
-
} | undefined, never> | import("@equinor/fusion-observable").PayloadAction<import("./BookmarkClient.interface").BookmarksFilter | undefined, "fetch_bookmarks::request", {
|
|
23
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<string, "add_favourite_bookmark::success", {
|
|
26
24
|
ref: string;
|
|
27
|
-
}
|
|
28
|
-
bookmarkId: string;
|
|
29
|
-
updates: import("./BookmarkClient.interface").BookmarkUpdate;
|
|
30
|
-
}, "set_bookmark::request", {
|
|
25
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<string, "delete_bookmark::request", {
|
|
31
26
|
ref: string;
|
|
32
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<
|
|
27
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<string, "delete_bookmark::success", {
|
|
33
28
|
ref: string;
|
|
34
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<string, "
|
|
29
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<string, "fetch_bookmark::request", {
|
|
35
30
|
ref: string;
|
|
36
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<string, "
|
|
31
|
+
} | undefined, never> | import("@equinor/fusion-observable").PayloadAction<string, "fetch_bookmark_payload::request", {
|
|
37
32
|
ref: string;
|
|
38
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<string, "
|
|
33
|
+
} | undefined, never> | import("@equinor/fusion-observable").PayloadAction<string, "remove_bookmark::request", {
|
|
39
34
|
ref: string;
|
|
40
35
|
}, never> | import("@equinor/fusion-observable").PayloadAction<string, "remove_favourite_bookmark::request", {
|
|
41
36
|
ref: string;
|
|
42
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<
|
|
37
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<string, "remove_favourite_bookmark::success", {
|
|
43
38
|
ref: string;
|
|
44
|
-
}
|
|
39
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<import("./types").Bookmark<any>, "create_bookmark::success", {
|
|
45
40
|
ref: string;
|
|
46
|
-
}
|
|
47
|
-
bookmarkId: string;
|
|
48
|
-
data: import("./types").BookmarkData;
|
|
49
|
-
}, "fetch_bookmark_payload::success", {
|
|
41
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<import("./types").Bookmark<any>, "set_bookmark::success", {
|
|
50
42
|
ref: string;
|
|
51
|
-
}
|
|
43
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkFlowError, "add_favourite_bookmark::failure", {
|
|
52
44
|
ref: string;
|
|
53
|
-
}
|
|
45
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkFlowError, "create_bookmark::failure", {
|
|
46
|
+
ref: string;
|
|
47
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkFlowError, "delete_bookmark::failure", {
|
|
48
|
+
ref: string;
|
|
49
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkFlowError, "fetch_bookmark::failure", {
|
|
50
|
+
ref: string;
|
|
51
|
+
} | undefined, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkFlowError, "fetch_bookmark_payload::failure", {
|
|
54
52
|
ref: string;
|
|
55
53
|
} | undefined, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkFlowError, "fetch_bookmarks::failure", {
|
|
56
54
|
ref: string;
|
|
57
|
-
} | undefined, never> | import("@equinor/fusion-observable").PayloadAction<
|
|
55
|
+
} | undefined, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkFlowError, "remove_bookmark::failure", {
|
|
56
|
+
ref: string;
|
|
57
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkFlowError, "remove_favourite_bookmark::failure", {
|
|
58
58
|
ref: string;
|
|
59
59
|
}, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkFlowError, "set_bookmark::failure", {
|
|
60
60
|
ref: string;
|
|
61
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<import("./
|
|
61
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<import("./BookmarkClient.interface").BookmarkNew, "create_bookmark::request", {
|
|
62
62
|
ref: string;
|
|
63
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<
|
|
63
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkWithoutData, "fetch_bookmark::success", {
|
|
64
64
|
ref: string;
|
|
65
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<
|
|
65
|
+
} | undefined, never> | import("@equinor/fusion-observable").PayloadAction<import("./types").Bookmarks, "fetch_bookmarks::success", {
|
|
66
66
|
ref: string;
|
|
67
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<
|
|
67
|
+
} | undefined, never> | import("@equinor/fusion-observable").PayloadAction<{
|
|
68
|
+
bookmarkId: string;
|
|
69
|
+
data: import("./types").BookmarkData;
|
|
70
|
+
}, "fetch_bookmark_payload::success", {
|
|
71
|
+
ref: string;
|
|
72
|
+
} | undefined, never> | import("@equinor/fusion-observable").PayloadAction<{
|
|
73
|
+
bookmarkId: string;
|
|
74
|
+
updates: import("./BookmarkClient.interface").BookmarkUpdate;
|
|
75
|
+
}, "set_bookmark::request", {
|
|
68
76
|
ref: string;
|
|
69
77
|
}, never> | import("@equinor/fusion-observable").PayloadAction<{
|
|
70
|
-
type:
|
|
78
|
+
type: 'delete_bookmark' | 'remove_favourite_bookmark';
|
|
71
79
|
bookmarkId: string;
|
|
72
80
|
}, "remove_bookmark::success", {
|
|
73
81
|
ref: string;
|
|
74
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<
|
|
75
|
-
ref: string;
|
|
76
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<string, "add_favourite_bookmark::success", {
|
|
77
|
-
ref: string;
|
|
78
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkFlowError, "add_favourite_bookmark::failure", {
|
|
79
|
-
ref: string;
|
|
80
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<string, "remove_favourite_bookmark::success", {
|
|
81
|
-
ref: string;
|
|
82
|
-
}, never> | import("@equinor/fusion-observable").PayloadAction<BookmarkFlowError, "remove_favourite_bookmark::failure", {
|
|
82
|
+
}, never> | import("@equinor/fusion-observable").PayloadAction<import("./BookmarkClient.interface").BookmarksFilter | undefined, "fetch_bookmarks::request", {
|
|
83
83
|
ref: string;
|
|
84
|
-
}, never>>;
|
|
84
|
+
} | undefined, never>>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FlowSubject, type ActionBaseType } from '@equinor/fusion-observable';
|
|
2
|
-
import type { BookmarkActions } from './
|
|
3
|
-
import type { BookmarkFlowError } from './
|
|
2
|
+
import type { BookmarkActions } from './bookmark-actions';
|
|
3
|
+
import type { BookmarkFlowError } from './BookmarkFlowError';
|
|
4
4
|
import type { IBookmarkClient } from './BookmarkClient.interface';
|
|
5
5
|
import type { Bookmark, BookmarkWithoutData } from './types';
|
|
6
6
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IModulesConfigurator } from '@equinor/fusion-framework-module';
|
|
2
|
-
import type { BookmarkModuleConfigurator } from './
|
|
2
|
+
import type { BookmarkModuleConfigurator } from './BookmarkModuleConfigurator';
|
|
3
3
|
/**
|
|
4
4
|
* Enables the bookmark module on a Fusion Framework module configurator.
|
|
5
5
|
*
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Bookmark module for the Fusion Framework.
|
|
3
|
+
*
|
|
4
|
+
* Provides bookmark management (create, update, delete, favourite) with
|
|
5
|
+
* application-scoped payloads and event-driven state updates.
|
|
6
|
+
*
|
|
7
|
+
* @see {@link enableBookmark} to enable the module in a configurator.
|
|
8
|
+
* @see {@link BookmarkProvider} for the runtime provider API.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
export { BookmarkModuleConfigurator } from './BookmarkModuleConfigurator';
|
|
2
13
|
export type { IBookmarkClient, BookmarkNew, BookmarkUpdate, BookmarksFilter, } from './BookmarkClient.interface';
|
|
3
14
|
export { default, BookmarkModule, module as bookmarkModule, moduleKey as bookmarkModuleKey, } from './bookmark-module';
|
|
4
15
|
export { BookmarkProvider } from './BookmarkProvider';
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "4.0.
|
|
1
|
+
export declare const version = "4.0.4";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@equinor/fusion-framework-module-bookmark",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.4",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist/esm/index.js",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -41,19 +41,19 @@
|
|
|
41
41
|
"immer": "^11.0.0",
|
|
42
42
|
"rxjs": "^7.8.1",
|
|
43
43
|
"uuid": "^14.0.0",
|
|
44
|
-
"@equinor/fusion-framework-module": "^6.
|
|
45
|
-
"@equinor/fusion-
|
|
46
|
-
"@equinor/fusion-
|
|
47
|
-
"@equinor/fusion-query": "^7.0.
|
|
44
|
+
"@equinor/fusion-framework-module": "^6.1.1",
|
|
45
|
+
"@equinor/fusion-log": "^2.0.2",
|
|
46
|
+
"@equinor/fusion-observable": "^9.1.1",
|
|
47
|
+
"@equinor/fusion-query": "^7.0.3"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"typescript": "^
|
|
50
|
+
"typescript": "^7.0.2",
|
|
51
51
|
"zod": "^4.4.3",
|
|
52
|
-
"@equinor/fusion-framework-module-
|
|
53
|
-
"@equinor/fusion-framework-module-
|
|
54
|
-
"@equinor/fusion-framework-module-
|
|
55
|
-
"@equinor/fusion-framework-module-
|
|
56
|
-
"@equinor/fusion-framework-module-services": "^8.0.
|
|
52
|
+
"@equinor/fusion-framework-module-app": "^8.0.4",
|
|
53
|
+
"@equinor/fusion-framework-module-context": "^8.0.1",
|
|
54
|
+
"@equinor/fusion-framework-module-event": "^6.0.1",
|
|
55
|
+
"@equinor/fusion-framework-module-http": "^8.0.5",
|
|
56
|
+
"@equinor/fusion-framework-module-services": "^8.0.3"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"build": "tsc -b"
|
package/src/BookmarkClient.ts
CHANGED
|
@@ -82,6 +82,7 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
82
82
|
* Constructs a new `BookmarkClient` instance with the provided `BookmarksApiClient`.
|
|
83
83
|
*
|
|
84
84
|
* @param api - The `BookmarksApiClient` instance to use for making API requests.
|
|
85
|
+
* @param options - Optional client options, such as the cache expiry time.
|
|
85
86
|
*/
|
|
86
87
|
constructor(api: BookmarksApiClient<'json$'>, options?: { expire?: number }) {
|
|
87
88
|
this.#api = api;
|
|
@@ -92,6 +93,7 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
92
93
|
this.#queryBookmark = new Query({
|
|
93
94
|
client: {
|
|
94
95
|
fn: (args: { bookmarkId: string }) => {
|
|
96
|
+
// strip the payload from the fetched bookmark before caching
|
|
95
97
|
return this.#api.get('v2', args).pipe(map(parseBookmarkWithoutPayload));
|
|
96
98
|
},
|
|
97
99
|
},
|
|
@@ -103,9 +105,13 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
103
105
|
this.#queryBookmarks = new Query({
|
|
104
106
|
client: {
|
|
105
107
|
fn: (filter?: BookmarksFilter) => {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
// strip the payload from each fetched bookmark before caching
|
|
109
|
+
return this.#api.query('v2', { filter }).pipe(
|
|
110
|
+
map((res) =>
|
|
111
|
+
// strip the payload field from each bookmark
|
|
112
|
+
res.map(parseBookmarkWithoutPayload),
|
|
113
|
+
),
|
|
114
|
+
);
|
|
109
115
|
},
|
|
110
116
|
},
|
|
111
117
|
key: (args) => JSON.stringify(args ?? ''),
|
|
@@ -115,6 +121,7 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
115
121
|
this.#queryBookmarkData = new Query({
|
|
116
122
|
client: {
|
|
117
123
|
fn: (args: { bookmarkId: string }) => {
|
|
124
|
+
// extract only the payload from the API response
|
|
118
125
|
return this.#api.getPayload('v1', args).pipe(map((res) => res.payload));
|
|
119
126
|
},
|
|
120
127
|
},
|
|
@@ -130,16 +137,19 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
130
137
|
|
|
131
138
|
/** @inheritdoc */
|
|
132
139
|
public getAllBookmarks(filter?: BookmarksFilter): ObservableInput<Bookmark[]> {
|
|
140
|
+
// unwrap the query result value
|
|
133
141
|
return this.#queryBookmarks.query(filter).pipe(map((res) => res.value as Bookmark[]));
|
|
134
142
|
}
|
|
135
143
|
|
|
136
144
|
/** @inheritdoc */
|
|
137
145
|
public getBookmarkById(bookmarkId: string): ObservableInput<BookmarkWithoutData> {
|
|
146
|
+
// unwrap the query result value
|
|
138
147
|
return this.#queryBookmark.query({ bookmarkId }).pipe(map((res) => res.value));
|
|
139
148
|
}
|
|
140
149
|
|
|
141
150
|
/** @inheritdoc */
|
|
142
151
|
public getBookmarkData<T extends BookmarkData>(bookmarkId: string): ObservableInput<T> {
|
|
152
|
+
// unwrap the query result value
|
|
143
153
|
return this.#queryBookmarkData.query({ bookmarkId }).pipe(map((res): T => res.value as T));
|
|
144
154
|
}
|
|
145
155
|
|
|
@@ -148,9 +158,11 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
148
158
|
bookmarkId: string,
|
|
149
159
|
data: T,
|
|
150
160
|
): ObservableInput<T> {
|
|
161
|
+
// update the payload cache once the mutation succeeds
|
|
151
162
|
return this.#api.patch('v1', { bookmarkId, updates: { payload: data } }).pipe(
|
|
152
163
|
map((res) => res.payload as T),
|
|
153
164
|
tap((updatedData) => {
|
|
165
|
+
// only update the cache when data was actually returned
|
|
154
166
|
if (updatedData) {
|
|
155
167
|
this.#queryBookmarkData.mutate(
|
|
156
168
|
{ bookmarkId },
|
|
@@ -166,6 +178,7 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
166
178
|
public createBookmark<T extends BookmarkData>(
|
|
167
179
|
newBookmark: BookmarkNew<T>,
|
|
168
180
|
): ObservableInput<Bookmark<T>> {
|
|
181
|
+
// parse the response and update caches once the bookmark is created
|
|
169
182
|
return this.#api.create('v1', newBookmark).pipe(
|
|
170
183
|
map((response) => parseBookmark<T>(response)),
|
|
171
184
|
/** update the bookmark cache */
|
|
@@ -177,6 +190,7 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
177
190
|
{ value: bookmark, updated: Date.now() },
|
|
178
191
|
{ allowCreation: true },
|
|
179
192
|
);
|
|
193
|
+
// only cache the payload if the created bookmark has one
|
|
180
194
|
if (payload) {
|
|
181
195
|
this.#queryBookmarkData.mutate(
|
|
182
196
|
{ bookmarkId: bookmark.id },
|
|
@@ -194,6 +208,7 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
194
208
|
bookmarkId: string,
|
|
195
209
|
updates: BookmarkUpdate<T>,
|
|
196
210
|
): ObservableInput<Bookmark<T>> {
|
|
211
|
+
// parse the response and share it across the cache-update subscriptions below
|
|
197
212
|
const update$ = this.#api.patch('v1', { bookmarkId, updates: updates }).pipe(
|
|
198
213
|
map((response) => parseBookmark<T>(response)),
|
|
199
214
|
shareReplay(),
|
|
@@ -217,6 +232,7 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
217
232
|
subscriber.add(
|
|
218
233
|
update$.subscribe((updatedBookmark) => {
|
|
219
234
|
const { payload } = updatedBookmark;
|
|
235
|
+
// only cache the payload when present, otherwise clear any stale cache entry
|
|
220
236
|
if (payload) {
|
|
221
237
|
this.#queryBookmarkData.mutate(
|
|
222
238
|
{
|
|
@@ -253,6 +269,7 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
253
269
|
|
|
254
270
|
/** @inheritdoc */
|
|
255
271
|
public addBookmarkToFavorites(bookmarkId: string): ObservableInput<boolean> {
|
|
272
|
+
// invalidate the bookmarks list cache once favorited
|
|
256
273
|
return this.#api
|
|
257
274
|
.addFavourite('v1', { bookmarkId })
|
|
258
275
|
.pipe(tap(() => this.#queryBookmarks.invalidate()));
|
|
@@ -260,6 +277,7 @@ export class BookmarkClient implements IBookmarkClient {
|
|
|
260
277
|
|
|
261
278
|
/** @inheritdoc */
|
|
262
279
|
public removeBookmarkFromFavorites(bookmarkId: string): ObservableInput<boolean> {
|
|
280
|
+
// invalidate the bookmarks list cache once unfavorited
|
|
263
281
|
return this.#api
|
|
264
282
|
.removeFavourite('v1', { bookmarkId })
|
|
265
283
|
.pipe(tap(() => this.#queryBookmarks.invalidate()));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ActionWithSuffix } from '@equinor/fusion-observable';
|
|
2
2
|
|
|
3
|
-
import type { BookmarkActions } from './
|
|
3
|
+
import type { BookmarkActions } from './bookmark-actions';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Error thrown inside bookmark store flows (side-effect pipelines) when an
|
|
@@ -10,6 +10,13 @@ import type { BookmarkActions } from './BookmarkProvider.actions';
|
|
|
10
10
|
* correlate errors back to specific operations.
|
|
11
11
|
*/
|
|
12
12
|
export class BookmarkFlowError extends Error {
|
|
13
|
+
/**
|
|
14
|
+
* Constructs a new `BookmarkFlowError`.
|
|
15
|
+
*
|
|
16
|
+
* @param message - Human-readable error message.
|
|
17
|
+
* @param action - The request action that triggered the failed flow.
|
|
18
|
+
* @param options - Optional `ErrorOptions` (e.g. `cause`).
|
|
19
|
+
*/
|
|
13
20
|
constructor(
|
|
14
21
|
message: string,
|
|
15
22
|
/** The request action that triggered the failed flow. */
|
|
@@ -28,9 +35,4 @@ export class BookmarkFlowError extends Error {
|
|
|
28
35
|
* Distinct from {@link BookmarkFlowError}, which is scoped to internal
|
|
29
36
|
* store flow pipelines.
|
|
30
37
|
*/
|
|
31
|
-
export
|
|
32
|
-
constructor(message: string, options?: ErrorOptions) {
|
|
33
|
-
super(message, options);
|
|
34
|
-
this.name = 'BookmarkProviderError';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
38
|
+
export { BookmarkProviderError } from './BookmarkProviderError';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ZodError } from 'zod';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
BaseConfigBuilder,
|
|
@@ -43,8 +43,16 @@ const parseInitialBookmarkConfigConfig = (initial?: unknown): BookmarkModuleConf
|
|
|
43
43
|
*/
|
|
44
44
|
export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModuleConfig> {
|
|
45
45
|
#log?: ILogger;
|
|
46
|
-
|
|
46
|
+
/** Default expiration time, in milliseconds, for bookmarks. */
|
|
47
|
+
defaultExpireTime = 1 * 60 * 1000;
|
|
47
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Constructs a new `BookmarkModuleConfigurator`.
|
|
51
|
+
*
|
|
52
|
+
* @param options - Optional configurator options.
|
|
53
|
+
* @param options.log - Logger instance inherited from the parent module, if any.
|
|
54
|
+
* @param options.ref - Reference to sibling module instances available during configuration.
|
|
55
|
+
*/
|
|
48
56
|
constructor(options?: { log?: ILogger; ref?: ModulesInstanceType<[BookmarkModule]> }) {
|
|
49
57
|
super();
|
|
50
58
|
const { log } = options ?? {};
|
|
@@ -64,6 +72,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
64
72
|
*/
|
|
65
73
|
public setLogLevel(level: LogLevel) {
|
|
66
74
|
this._set('logLevel', async () => level);
|
|
75
|
+
// propagate the level to the configurator's own logger, if one is set
|
|
67
76
|
if (this.#log) {
|
|
68
77
|
this.#log.level = level;
|
|
69
78
|
}
|
|
@@ -84,6 +93,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
84
93
|
public setClient(
|
|
85
94
|
client: ConfigBuilderCallback<BookmarkModuleConfig['client']> | BookmarkModuleConfig['client'],
|
|
86
95
|
) {
|
|
96
|
+
// a callback receives the module initializer and resolves the client itself
|
|
87
97
|
if (typeof client === 'function') {
|
|
88
98
|
this._set('client', (init) => client(init));
|
|
89
99
|
} else {
|
|
@@ -102,6 +112,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
102
112
|
public setParent(
|
|
103
113
|
parent: ConfigBuilderCallback<BookmarkModuleConfig['parent']> | BookmarkModuleConfig['parent'],
|
|
104
114
|
) {
|
|
115
|
+
// a callback receives the module initializer and resolves the parent itself
|
|
105
116
|
if (typeof parent === 'function') {
|
|
106
117
|
this._set('parent', (init) => parent(init));
|
|
107
118
|
} else {
|
|
@@ -128,6 +139,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
128
139
|
| ConfigBuilderCallback<BookmarkModuleConfig['sourceSystem']>
|
|
129
140
|
| BookmarkModuleConfig['sourceSystem'],
|
|
130
141
|
) {
|
|
142
|
+
// a callback receives the module initializer and resolves the source system itself
|
|
131
143
|
if (typeof sourceSystem === 'function') {
|
|
132
144
|
this._set('sourceSystem', sourceSystem);
|
|
133
145
|
} else {
|
|
@@ -167,6 +179,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
167
179
|
|
|
168
180
|
/**
|
|
169
181
|
* Sets a filter for the bookmark module.
|
|
182
|
+
* @template TKey - The filter key being set.
|
|
170
183
|
* @param key - The key of the filter to set.
|
|
171
184
|
* @param value - The value to set for the filter.
|
|
172
185
|
*
|
|
@@ -179,7 +192,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
179
192
|
value: BookmarkModuleConfig['filters'][TKey],
|
|
180
193
|
) {
|
|
181
194
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
182
|
-
// @ts-
|
|
195
|
+
// @ts-expect-error
|
|
183
196
|
this._set(`filters.${key}`, async () => value);
|
|
184
197
|
}
|
|
185
198
|
|
|
@@ -204,12 +217,14 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
204
217
|
|
|
205
218
|
// Check if parent and parent version compatible
|
|
206
219
|
const parentModules = init.ref as ModulesInstanceType<[BookmarkModule]>;
|
|
220
|
+
// only use the parent module's bookmark provider if it's actually present
|
|
207
221
|
if (parentModules && 'bookmark' in parentModules) {
|
|
208
222
|
const parent = parentModules.bookmark;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
223
|
+
// `parent` is narrowed to `{ version: unknown }` by the `'version' in parent` check below,
|
|
224
|
+
// so it must be cast through `unknown` to access `BookmarkProvider`-specific members.
|
|
225
|
+
const parentProvider = parent as unknown as BookmarkProvider;
|
|
226
|
+
// only inherit from a parent whose version satisfies the minimum supported range
|
|
227
|
+
if ('version' in parent && parentProvider.version.satisfies('>=2.0.0')) {
|
|
213
228
|
this._set('parent', async () => parent);
|
|
214
229
|
} else {
|
|
215
230
|
this.#log?.warn('invalid version of parent BookmarkProvider provided');
|
|
@@ -254,7 +269,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
254
269
|
*/
|
|
255
270
|
protected async _createDefaultContextResolver(
|
|
256
271
|
init: ConfigBuilderCallbackArgs,
|
|
257
|
-
): Promise<BookmarkModuleConfig['resolve']['context'] |
|
|
272
|
+
): Promise<BookmarkModuleConfig['resolve']['context'] | undefined> {
|
|
258
273
|
// Check if context module is available and use context provider if available
|
|
259
274
|
if (init.hasModule('context')) {
|
|
260
275
|
this.#log?.debug('Context module available, awaiting instance');
|
|
@@ -276,7 +291,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
276
291
|
*/
|
|
277
292
|
protected async _createDefaultApplicationResolver(
|
|
278
293
|
init: ConfigBuilderCallbackArgs,
|
|
279
|
-
): Promise<BookmarkModuleConfig['resolve']['application'] |
|
|
294
|
+
): Promise<BookmarkModuleConfig['resolve']['application'] | undefined> {
|
|
280
295
|
// Check if app module is available and use app provider if available
|
|
281
296
|
if (init.hasModule('app')) {
|
|
282
297
|
this.#log?.debug('App module available, awaiting instance');
|
|
@@ -285,6 +300,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
285
300
|
this.#log?.debug('App provider available, creating application resolver');
|
|
286
301
|
return async () => {
|
|
287
302
|
const app = appProvider.current;
|
|
303
|
+
// only resolve the application if there is a currently loaded app
|
|
288
304
|
if (app) {
|
|
289
305
|
return {
|
|
290
306
|
appKey: app.appKey,
|
|
@@ -297,6 +313,11 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
297
313
|
}
|
|
298
314
|
}
|
|
299
315
|
|
|
316
|
+
/**
|
|
317
|
+
* @internal Resolves the {@link AppModuleProvider} for the bookmark module.
|
|
318
|
+
* @param init - The configuration initialization object.
|
|
319
|
+
* @returns A promise that resolves to the app module provider, or undefined if unavailable.
|
|
320
|
+
*/
|
|
300
321
|
protected async _resolveAppProvider(
|
|
301
322
|
init: ConfigBuilderCallbackArgs,
|
|
302
323
|
): Promise<AppModuleProvider | undefined> {
|
|
@@ -316,7 +337,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
316
337
|
*/
|
|
317
338
|
protected async _resolveEventProvider(
|
|
318
339
|
init: ConfigBuilderCallbackArgs,
|
|
319
|
-
): Promise<BookmarkModuleConfig['eventProvider'] |
|
|
340
|
+
): Promise<BookmarkModuleConfig['eventProvider'] | undefined> {
|
|
320
341
|
// Check if event module is available
|
|
321
342
|
if (init.hasModule('event')) {
|
|
322
343
|
this.#log?.debug('Event module available, awaiting instance');
|
|
@@ -331,12 +352,12 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
331
352
|
*/
|
|
332
353
|
protected async _createDefaultClient(
|
|
333
354
|
init: ConfigBuilderCallbackArgs,
|
|
334
|
-
): Promise<BookmarkModuleConfig['client'] |
|
|
355
|
+
): Promise<BookmarkModuleConfig['client'] | undefined> {
|
|
335
356
|
try {
|
|
336
357
|
const apiProvider = await this._getServiceProvider(init);
|
|
337
358
|
const api = await apiProvider.createBookmarksClient('json$');
|
|
338
359
|
return new BookmarkClient(api);
|
|
339
|
-
} catch (
|
|
360
|
+
} catch (_err) {
|
|
340
361
|
this.#log?.warn('Failed to create bookmark api client');
|
|
341
362
|
}
|
|
342
363
|
}
|
|
@@ -345,6 +366,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
345
366
|
* @internal retrieves the service provider from the configuration initialization object.
|
|
346
367
|
* @param init - The configuration initialization object.
|
|
347
368
|
* @returns A promise that resolves to the service provider.
|
|
369
|
+
* @throws {Error} When no services module or parent service module is available.
|
|
348
370
|
*/
|
|
349
371
|
protected async _getServiceProvider(init: ConfigBuilderCallbackArgs): Promise<IApiProvider> {
|
|
350
372
|
// check if services module is available
|
|
@@ -357,6 +379,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
357
379
|
|
|
358
380
|
// check if parent has services module
|
|
359
381
|
const parentServiceModule = (init.ref as ModulesInstanceType<[ServicesModule]>)?.services;
|
|
382
|
+
// reuse the parent's service module if one is available
|
|
360
383
|
if (parentServiceModule) {
|
|
361
384
|
return parentServiceModule;
|
|
362
385
|
}
|
|
@@ -366,6 +389,13 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
366
389
|
throw Error('[BookmarkConfigurator] No service provider configures [ServicesModule] ');
|
|
367
390
|
}
|
|
368
391
|
|
|
392
|
+
/**
|
|
393
|
+
* @internal Validates and normalizes the resolved config before it's returned from `build`.
|
|
394
|
+
* @param config - The partially-resolved bookmark module config.
|
|
395
|
+
* @param _init - The configuration initialization object (unused).
|
|
396
|
+
* @returns The validated {@link BookmarkModuleConfig}.
|
|
397
|
+
* @throws {ZodError} When the config fails schema validation.
|
|
398
|
+
*/
|
|
369
399
|
protected async _processConfig(
|
|
370
400
|
config: Partial<BookmarkModuleConfig>,
|
|
371
401
|
_init: ConfigBuilderCallbackArgs,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// biome-ignore-all lint/suspicious/noExplicitAny: `BookmarkData = any` generic defaults must remain bivariant — `unknown` breaks assignability of concrete `Bookmark<T>`/`BookmarkPayloadGenerator<TData>` instances to the default-typed generic
|
|
2
2
|
import type { Observable, ObservableInput } from 'rxjs';
|
|
3
3
|
import type { Bookmark, BookmarkData, BookmarkWithoutData } from './types';
|
|
4
4
|
import type { BookmarkNew, BookmarkUpdate } from './BookmarkClient.interface';
|
|
5
5
|
import type { BookmarkProviderEventMap } from './BookmarkProvider.events';
|
|
6
|
-
import type { BookmarkState } from './
|
|
6
|
+
import type { BookmarkState } from './create-bookmark-store';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Arguments for creating a bookmark via {@link IBookmarkProvider.createBookmark}.
|
|
@@ -45,6 +45,7 @@ export type BookmarkUpdateOptions = {
|
|
|
45
45
|
export type BookmarkPayloadGenerator<TData extends BookmarkData = any> = (
|
|
46
46
|
payload?: Partial<TData> | null,
|
|
47
47
|
initial?: Partial<TData> | null,
|
|
48
|
+
// biome-ignore lint/suspicious/noConfusingVoidType: `void` here relies on TypeScript's special-cased "void-returning callback accepts any return value" behavior for draft-mutating generators — `undefined` would break assignability of generators that only conditionally return a partial payload
|
|
48
49
|
) => Promise<Partial<TData> | void> | Partial<TData> | void;
|
|
49
50
|
|
|
50
51
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { BookmarkFlowError } from './
|
|
2
|
-
import type { BookmarkState } from './
|
|
1
|
+
import type { BookmarkFlowError } from './BookmarkFlowError';
|
|
2
|
+
import type { BookmarkState } from './create-bookmark-store';
|
|
3
3
|
import type { Bookmark, BookmarkData } from './types';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -20,6 +20,8 @@ export const bookmarksSelector = (state: BookmarkState): Bookmark[] => {
|
|
|
20
20
|
* @param id - The bookmark identifier to look up.
|
|
21
21
|
* @returns The matching bookmark, or `undefined` if not found.
|
|
22
22
|
*/
|
|
23
|
+
// tightly coupled group of store selectors
|
|
24
|
+
// fusion-lint-disable-next-line single-export-per-file
|
|
23
25
|
export const bookmarkSelector = <T extends BookmarkData>(
|
|
24
26
|
state: BookmarkState,
|
|
25
27
|
id: string,
|
|
@@ -34,6 +36,8 @@ export const bookmarkSelector = <T extends BookmarkData>(
|
|
|
34
36
|
* @param state - The current bookmark store state.
|
|
35
37
|
* @returns The active bookmark, `null` if explicitly cleared, or `undefined` if never set.
|
|
36
38
|
*/
|
|
39
|
+
// tightly coupled group of store selectors
|
|
40
|
+
// fusion-lint-disable-next-line single-export-per-file
|
|
37
41
|
export const activeBookmarkSelector = <T extends BookmarkData>(
|
|
38
42
|
state: BookmarkState,
|
|
39
43
|
): Bookmark<T> | null | undefined => {
|
|
@@ -46,6 +50,8 @@ export const activeBookmarkSelector = <T extends BookmarkData>(
|
|
|
46
50
|
* @param state - The bookmark state.
|
|
47
51
|
* @returns The status from the bookmark state.
|
|
48
52
|
*/
|
|
53
|
+
// tightly coupled group of store selectors
|
|
54
|
+
// fusion-lint-disable-next-line single-export-per-file
|
|
49
55
|
export const statusSelector = (state: BookmarkState): BookmarkState['status'] => {
|
|
50
56
|
return state.status;
|
|
51
57
|
};
|
|
@@ -56,6 +62,8 @@ export const statusSelector = (state: BookmarkState): BookmarkState['status'] =>
|
|
|
56
62
|
* @param state - The bookmark state.
|
|
57
63
|
* @returns An array of bookmark flow errors.
|
|
58
64
|
*/
|
|
65
|
+
// tightly coupled group of store selectors
|
|
66
|
+
// fusion-lint-disable-next-line single-export-per-file
|
|
59
67
|
export const errorsSelector = (state: BookmarkState): Array<BookmarkFlowError> => {
|
|
60
68
|
return Object.values(state.errors);
|
|
61
69
|
};
|