@equinor/fusion-framework-module-bookmark 4.0.2 → 4.0.3
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 +13 -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} +36 -5
- 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} +9 -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} +40 -11
- 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.3";
|
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.3",
|
|
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-
|
|
44
|
+
"@equinor/fusion-framework-module": "^6.1.1",
|
|
45
|
+
"@equinor/fusion-query": "^7.0.2",
|
|
46
|
+
"@equinor/fusion-observable": "^9.1.1",
|
|
47
|
+
"@equinor/fusion-log": "^2.0.1"
|
|
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.3",
|
|
53
|
+
"@equinor/fusion-framework-module-event": "^6.0.1",
|
|
54
|
+
"@equinor/fusion-framework-module-context": "^8.0.1",
|
|
55
|
+
"@equinor/fusion-framework-module-http": "^8.0.4",
|
|
56
|
+
"@equinor/fusion-framework-module-services": "^8.0.2"
|
|
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,
|
|
@@ -45,6 +45,13 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
45
45
|
#log?: ILogger;
|
|
46
46
|
defaultExpireTime = 1 * 60 * 1000; // Default expiration time for bookmarks
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Constructs a new `BookmarkModuleConfigurator`.
|
|
50
|
+
*
|
|
51
|
+
* @param options - Optional configurator options.
|
|
52
|
+
* @param options.log - Logger instance inherited from the parent module, if any.
|
|
53
|
+
* @param options.ref - Reference to sibling module instances available during configuration.
|
|
54
|
+
*/
|
|
48
55
|
constructor(options?: { log?: ILogger; ref?: ModulesInstanceType<[BookmarkModule]> }) {
|
|
49
56
|
super();
|
|
50
57
|
const { log } = options ?? {};
|
|
@@ -64,6 +71,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
64
71
|
*/
|
|
65
72
|
public setLogLevel(level: LogLevel) {
|
|
66
73
|
this._set('logLevel', async () => level);
|
|
74
|
+
// propagate the level to the configurator's own logger, if one is set
|
|
67
75
|
if (this.#log) {
|
|
68
76
|
this.#log.level = level;
|
|
69
77
|
}
|
|
@@ -84,6 +92,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
84
92
|
public setClient(
|
|
85
93
|
client: ConfigBuilderCallback<BookmarkModuleConfig['client']> | BookmarkModuleConfig['client'],
|
|
86
94
|
) {
|
|
95
|
+
// a callback receives the module initializer and resolves the client itself
|
|
87
96
|
if (typeof client === 'function') {
|
|
88
97
|
this._set('client', (init) => client(init));
|
|
89
98
|
} else {
|
|
@@ -102,6 +111,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
102
111
|
public setParent(
|
|
103
112
|
parent: ConfigBuilderCallback<BookmarkModuleConfig['parent']> | BookmarkModuleConfig['parent'],
|
|
104
113
|
) {
|
|
114
|
+
// a callback receives the module initializer and resolves the parent itself
|
|
105
115
|
if (typeof parent === 'function') {
|
|
106
116
|
this._set('parent', (init) => parent(init));
|
|
107
117
|
} else {
|
|
@@ -128,6 +138,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
128
138
|
| ConfigBuilderCallback<BookmarkModuleConfig['sourceSystem']>
|
|
129
139
|
| BookmarkModuleConfig['sourceSystem'],
|
|
130
140
|
) {
|
|
141
|
+
// a callback receives the module initializer and resolves the source system itself
|
|
131
142
|
if (typeof sourceSystem === 'function') {
|
|
132
143
|
this._set('sourceSystem', sourceSystem);
|
|
133
144
|
} else {
|
|
@@ -167,6 +178,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
167
178
|
|
|
168
179
|
/**
|
|
169
180
|
* Sets a filter for the bookmark module.
|
|
181
|
+
* @template TKey - The filter key being set.
|
|
170
182
|
* @param key - The key of the filter to set.
|
|
171
183
|
* @param value - The value to set for the filter.
|
|
172
184
|
*
|
|
@@ -179,7 +191,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
179
191
|
value: BookmarkModuleConfig['filters'][TKey],
|
|
180
192
|
) {
|
|
181
193
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
182
|
-
// @ts-
|
|
194
|
+
// @ts-expect-error
|
|
183
195
|
this._set(`filters.${key}`, async () => value);
|
|
184
196
|
}
|
|
185
197
|
|
|
@@ -204,12 +216,14 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
204
216
|
|
|
205
217
|
// Check if parent and parent version compatible
|
|
206
218
|
const parentModules = init.ref as ModulesInstanceType<[BookmarkModule]>;
|
|
219
|
+
// only use the parent module's bookmark provider if it's actually present
|
|
207
220
|
if (parentModules && 'bookmark' in parentModules) {
|
|
208
221
|
const parent = parentModules.bookmark;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
222
|
+
// `parent` is narrowed to `{ version: unknown }` by the `'version' in parent` check below,
|
|
223
|
+
// so it must be cast through `unknown` to access `BookmarkProvider`-specific members.
|
|
224
|
+
const parentProvider = parent as unknown as BookmarkProvider;
|
|
225
|
+
// only inherit from a parent whose version satisfies the minimum supported range
|
|
226
|
+
if ('version' in parent && parentProvider.version.satisfies('>=2.0.0')) {
|
|
213
227
|
this._set('parent', async () => parent);
|
|
214
228
|
} else {
|
|
215
229
|
this.#log?.warn('invalid version of parent BookmarkProvider provided');
|
|
@@ -254,7 +268,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
254
268
|
*/
|
|
255
269
|
protected async _createDefaultContextResolver(
|
|
256
270
|
init: ConfigBuilderCallbackArgs,
|
|
257
|
-
): Promise<BookmarkModuleConfig['resolve']['context'] |
|
|
271
|
+
): Promise<BookmarkModuleConfig['resolve']['context'] | undefined> {
|
|
258
272
|
// Check if context module is available and use context provider if available
|
|
259
273
|
if (init.hasModule('context')) {
|
|
260
274
|
this.#log?.debug('Context module available, awaiting instance');
|
|
@@ -276,7 +290,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
276
290
|
*/
|
|
277
291
|
protected async _createDefaultApplicationResolver(
|
|
278
292
|
init: ConfigBuilderCallbackArgs,
|
|
279
|
-
): Promise<BookmarkModuleConfig['resolve']['application'] |
|
|
293
|
+
): Promise<BookmarkModuleConfig['resolve']['application'] | undefined> {
|
|
280
294
|
// Check if app module is available and use app provider if available
|
|
281
295
|
if (init.hasModule('app')) {
|
|
282
296
|
this.#log?.debug('App module available, awaiting instance');
|
|
@@ -285,6 +299,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
285
299
|
this.#log?.debug('App provider available, creating application resolver');
|
|
286
300
|
return async () => {
|
|
287
301
|
const app = appProvider.current;
|
|
302
|
+
// only resolve the application if there is a currently loaded app
|
|
288
303
|
if (app) {
|
|
289
304
|
return {
|
|
290
305
|
appKey: app.appKey,
|
|
@@ -297,6 +312,11 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
297
312
|
}
|
|
298
313
|
}
|
|
299
314
|
|
|
315
|
+
/**
|
|
316
|
+
* @internal Resolves the {@link AppModuleProvider} for the bookmark module.
|
|
317
|
+
* @param init - The configuration initialization object.
|
|
318
|
+
* @returns A promise that resolves to the app module provider, or undefined if unavailable.
|
|
319
|
+
*/
|
|
300
320
|
protected async _resolveAppProvider(
|
|
301
321
|
init: ConfigBuilderCallbackArgs,
|
|
302
322
|
): Promise<AppModuleProvider | undefined> {
|
|
@@ -316,7 +336,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
316
336
|
*/
|
|
317
337
|
protected async _resolveEventProvider(
|
|
318
338
|
init: ConfigBuilderCallbackArgs,
|
|
319
|
-
): Promise<BookmarkModuleConfig['eventProvider'] |
|
|
339
|
+
): Promise<BookmarkModuleConfig['eventProvider'] | undefined> {
|
|
320
340
|
// Check if event module is available
|
|
321
341
|
if (init.hasModule('event')) {
|
|
322
342
|
this.#log?.debug('Event module available, awaiting instance');
|
|
@@ -331,12 +351,12 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
331
351
|
*/
|
|
332
352
|
protected async _createDefaultClient(
|
|
333
353
|
init: ConfigBuilderCallbackArgs,
|
|
334
|
-
): Promise<BookmarkModuleConfig['client'] |
|
|
354
|
+
): Promise<BookmarkModuleConfig['client'] | undefined> {
|
|
335
355
|
try {
|
|
336
356
|
const apiProvider = await this._getServiceProvider(init);
|
|
337
357
|
const api = await apiProvider.createBookmarksClient('json$');
|
|
338
358
|
return new BookmarkClient(api);
|
|
339
|
-
} catch (
|
|
359
|
+
} catch (_err) {
|
|
340
360
|
this.#log?.warn('Failed to create bookmark api client');
|
|
341
361
|
}
|
|
342
362
|
}
|
|
@@ -345,6 +365,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
345
365
|
* @internal retrieves the service provider from the configuration initialization object.
|
|
346
366
|
* @param init - The configuration initialization object.
|
|
347
367
|
* @returns A promise that resolves to the service provider.
|
|
368
|
+
* @throws {Error} When no services module or parent service module is available.
|
|
348
369
|
*/
|
|
349
370
|
protected async _getServiceProvider(init: ConfigBuilderCallbackArgs): Promise<IApiProvider> {
|
|
350
371
|
// check if services module is available
|
|
@@ -357,6 +378,7 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
357
378
|
|
|
358
379
|
// check if parent has services module
|
|
359
380
|
const parentServiceModule = (init.ref as ModulesInstanceType<[ServicesModule]>)?.services;
|
|
381
|
+
// reuse the parent's service module if one is available
|
|
360
382
|
if (parentServiceModule) {
|
|
361
383
|
return parentServiceModule;
|
|
362
384
|
}
|
|
@@ -366,6 +388,13 @@ export class BookmarkModuleConfigurator extends BaseConfigBuilder<BookmarkModule
|
|
|
366
388
|
throw Error('[BookmarkConfigurator] No service provider configures [ServicesModule] ');
|
|
367
389
|
}
|
|
368
390
|
|
|
391
|
+
/**
|
|
392
|
+
* @internal Validates and normalizes the resolved config before it's returned from `build`.
|
|
393
|
+
* @param config - The partially-resolved bookmark module config.
|
|
394
|
+
* @param _init - The configuration initialization object (unused).
|
|
395
|
+
* @returns The validated {@link BookmarkModuleConfig}.
|
|
396
|
+
* @throws {ZodError} When the config fails schema validation.
|
|
397
|
+
*/
|
|
369
398
|
protected async _processConfig(
|
|
370
399
|
config: Partial<BookmarkModuleConfig>,
|
|
371
400
|
_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
|
};
|