@equinor/fusion-framework-module-bookmark 4.1.0 → 4.1.2

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 (48) hide show
  1. package/dist/esm/BookmarkProvider.js +10 -5
  2. package/dist/esm/BookmarkProvider.js.map +1 -1
  3. package/dist/esm/__tests__/BookmarkProvider.test.js +34 -0
  4. package/dist/esm/__tests__/BookmarkProvider.test.js.map +1 -0
  5. package/dist/esm/version.js +1 -1
  6. package/dist/tsconfig.tsbuildinfo +1 -1
  7. package/dist/types/BookmarkProvider.d.ts +5 -2
  8. package/dist/types/__tests__/BookmarkProvider.test.d.ts +1 -0
  9. package/dist/types/version.d.ts +1 -1
  10. package/package.json +13 -10
  11. package/CHANGELOG.md +0 -821
  12. package/src/BookmarkClient.interface.ts +0 -157
  13. package/src/BookmarkClient.ts +0 -290
  14. package/src/BookmarkFlowError.ts +0 -38
  15. package/src/BookmarkModuleConfigurator.ts +0 -412
  16. package/src/BookmarkProvider.events.ts +0 -87
  17. package/src/BookmarkProvider.interface.ts +0 -180
  18. package/src/BookmarkProvider.selectors.ts +0 -69
  19. package/src/BookmarkProvider.ts +0 -1549
  20. package/src/BookmarkProviderError.ts +0 -19
  21. package/src/__tests__/mock/bookmark-mock.test.ts +0 -199
  22. package/src/bookmark-actions.ts +0 -132
  23. package/src/bookmark-config.schema.ts +0 -55
  24. package/src/bookmark-flows/bookmark-api-flows.ts +0 -45
  25. package/src/bookmark-flows/handle-add-bookmark-as-favorite.ts +0 -49
  26. package/src/bookmark-flows/handle-create-bookmark.ts +0 -47
  27. package/src/bookmark-flows/handle-delete-bookmark.ts +0 -47
  28. package/src/bookmark-flows/handle-fetch-all-bookmark.ts +0 -53
  29. package/src/bookmark-flows/handle-fetch-bookmark-data.ts +0 -58
  30. package/src/bookmark-flows/handle-fetch-bookmark.ts +0 -64
  31. package/src/bookmark-flows/handle-remove-bookmark-from-favorites.ts +0 -49
  32. package/src/bookmark-flows/handle-remove-bookmark.ts +0 -76
  33. package/src/bookmark-flows/handle-update-bookmark.ts +0 -48
  34. package/src/bookmark-flows/index.ts +0 -10
  35. package/src/bookmark-module.ts +0 -98
  36. package/src/bookmark.schemas.ts +0 -81
  37. package/src/create-bookmark-reducer.ts +0 -149
  38. package/src/create-bookmark-store.ts +0 -61
  39. package/src/enable-bookmark.ts +0 -44
  40. package/src/index.ts +0 -43
  41. package/src/mock/BookmarkMockClient.ts +0 -310
  42. package/src/mock/BookmarkMockConfigurator.ts +0 -159
  43. package/src/mock/index.ts +0 -25
  44. package/src/mock/module.ts +0 -64
  45. package/src/types.ts +0 -121
  46. package/src/version.ts +0 -2
  47. package/tsconfig.json +0 -30
  48. package/vitest.config.ts +0 -11
@@ -1,157 +0,0 @@
1
- import type { ObservableInput } from 'rxjs';
2
- import type { Bookmark, BookmarkData, BookmarkWithoutData } from './types';
3
-
4
- /**
5
- * Defines the shape of a filter for querying bookmarks.
6
- * @property {string} [appKey] - The app key to filter bookmarks by.
7
- * @property {string} [contextId] - The context ID to filter bookmarks by.
8
- * @property {object} [sourceSystem] - The source system to filter bookmarks by.
9
- * @property {string} [sourceSystem.identifier] - The identifier of the source system.
10
- * @property {string} [sourceSystem.name] - The name of the source system.
11
- * @property {string} [sourceSystem.subSystem] - The sub-system of the source system.
12
- */
13
- export type BookmarksFilter = {
14
- appKey?: string;
15
- contextId?: string;
16
- sourceSystem?: {
17
- identifier?: string;
18
- name?: string | null;
19
- subSystem?: string | null;
20
- };
21
- };
22
-
23
- /**
24
- * Defines the shape of an update to an existing bookmark.
25
- * @template T - The type of the payload data for the bookmark.
26
- * @property {string} [name] - The updated name of the bookmark.
27
- * @property {string} [description] - The updated description of the bookmark.
28
- * @property {boolean} [isShared] - Whether the bookmark is shared or not.
29
- * @property {T} [payload] - The updated payload data for the bookmark.
30
- */
31
- export type BookmarkUpdate<T extends BookmarkData = BookmarkData> = {
32
- name?: string;
33
- description?: string;
34
- isShared?: boolean;
35
- payload?: T | null;
36
- sourceSystem?: {
37
- identifier: string;
38
- name?: string | null;
39
- subSystem?: string | null;
40
- } | null;
41
- };
42
-
43
- /**
44
- * Defines the shape of a new bookmark to be created.
45
- * @template T - The type of the payload data for the bookmark.
46
- * @property {string} name - The name of the bookmark.
47
- * @property {string} appKey - The app key associated with the bookmark.
48
- * @property {string} [description] - The description of the bookmark.
49
- * @property {boolean} [isShared] - Whether the bookmark is shared or not.
50
- * @property {string} [contextId] - The context ID associated with the bookmark.
51
- * @property {object} [sourceSystem] - Information about the source system of the bookmark.
52
- * @property {string} [sourceSystem.identifier] - The identifier of the source system.
53
- * @property {string} [sourceSystem.name] - The name of the source system.
54
- * @property {string} [sourceSystem.subSystem] - The sub-system of the source system.
55
- * @property {T} [payload] - The payload data for the bookmark.
56
- */
57
- export type BookmarkNew<T extends BookmarkData = BookmarkData> = {
58
- name: string;
59
- appKey: string;
60
- description?: string;
61
- isShared?: boolean;
62
- contextId?: string;
63
- sourceSystem?: {
64
- identifier: string;
65
- name?: string;
66
- subSystem?: string;
67
- };
68
- payload?: T;
69
- };
70
-
71
- /**
72
- * Defines the interface for a Bookmarks client, which provides methods for managing bookmarks.
73
- */
74
- export interface IBookmarkClient {
75
- /**
76
- * Retrieves all bookmarks for the current user.
77
- * @template TPayload - The type of the payload data for the bookmarks.
78
- * @param args - Optional arguments to filter or customize the bookmark retrieval.
79
- * @returns An observable input containing an array of bookmarks.
80
- */
81
- getAllBookmarks: (filter?: BookmarksFilter) => ObservableInput<Array<Bookmark>>;
82
-
83
- /**
84
- * Retrieves a single bookmark by id.
85
- * @template TPayload - The type of the payload data for the bookmark.
86
- * @param bookmarkId - The id of the bookmark to retrieve.
87
- * @returns An observable input containing the requested bookmark.
88
- */
89
- getBookmarkById: (bookmarkId: string) => ObservableInput<BookmarkWithoutData>;
90
-
91
- /**
92
- * Retrieves the bookmark data for the specified bookmark ID.
93
- *
94
- * @param bookmarkId - The ID of the bookmark to retrieve data for.
95
- * @returns An observable that emits the bookmark data.
96
- */
97
- getBookmarkData: <T extends BookmarkData>(bookmarkId: string) => ObservableInput<T>;
98
-
99
- /**
100
- * Updates the data associated with a bookmark.
101
- *
102
- * @template T - The type of the data to be associated with the bookmark. Can be a record or null.
103
- * @param bookmarkId - The ID of the bookmark to update.
104
- * @param data - The new data to be associated with the bookmark.
105
- * @returns An observable that emits the updated data.
106
- */
107
- setBookmarkData<T extends BookmarkData | null>(bookmarkId: string, data: T): ObservableInput<T>;
108
-
109
- /**
110
- * Adds a bookmark to the current user's favorites.
111
- * @param bookmarkId - The id of the bookmark to add to favorites.
112
- * @returns An observable input containing a boolean indicating whether the operation was successful.
113
- */
114
- addBookmarkToFavorites: (bookmarkId: string) => ObservableInput<boolean>;
115
-
116
- /**
117
- * Removes a bookmark from the current user's favorites.
118
- * @param bookmarkId - The id of the bookmark to remove from favorites.
119
- * @returns An observable input containing a boolean indicating whether the operation was successful.
120
- */
121
- removeBookmarkFromFavorites: (bookmarkId: string) => ObservableInput<boolean>;
122
-
123
- /**
124
- * Verifies whether a bookmark is a favorite of the current user.
125
- * @param bookmarkId - The id of the bookmark to verify.
126
- * @returns An observable input containing a boolean indicating whether the bookmark is a favorite.
127
- */
128
- isBookmarkFavorite: (bookmarkId: string) => ObservableInput<boolean>;
129
-
130
- /**
131
- * Creates a new bookmark.
132
- * @template TPayload - The type of the payload data for the bookmark.
133
- * @param bookmark - The bookmark data to create.
134
- * @returns An observable input containing the created bookmark.
135
- */
136
- createBookmark: <T extends BookmarkData>(
137
- bookmark: BookmarkNew<T>,
138
- ) => ObservableInput<Bookmark<T>>;
139
-
140
- /**
141
- * Updates an existing bookmark.
142
- * @template TPayload - The type of the payload data for the bookmark.
143
- * @param bookmark - The bookmark data to update.
144
- * @returns An observable input containing the updated bookmark.
145
- */
146
- updateBookmark: <T extends BookmarkData>(
147
- bookmarkId: string,
148
- updates: BookmarkUpdate<T>,
149
- ) => ObservableInput<Bookmark<T>>;
150
-
151
- /**
152
- * Deletes a bookmark by id.
153
- * @param bookmarkId - The id of the bookmark to delete.
154
- * @returns An observable input containing a boolean indicating whether the operation was successful.
155
- */
156
- deleteBookmark: (bookmarkId: string) => ObservableInput<boolean>;
157
- }
@@ -1,290 +0,0 @@
1
- import { Observable, type ObservableInput } from 'rxjs';
2
- import { map, shareReplay, tap } from 'rxjs/operators';
3
-
4
- /**
5
- * Imports the `Query` type from the `@equinor/fusion-query` package.
6
- * This type is used to cache the results of API requests.
7
- */
8
- import { Query } from '@equinor/fusion-query';
9
-
10
- /**
11
- * Imports the `BookmarksApiClient` and `ApiBookmarkEntityV1` types from the `@equinor/fusion-framework-module-services/bookmarks` package.
12
- * These types are used to interact with the Fusion Bookmarks API and represent the API response entities.
13
- */
14
- import {
15
- type BookmarksApiClient,
16
- type ApiBookmarkSchema,
17
- ApiPersonSchema,
18
- type ApiVersion,
19
- } from '@equinor/fusion-framework-module-services/bookmarks';
20
-
21
- import type {
22
- IBookmarkClient,
23
- BookmarksFilter,
24
- BookmarkNew,
25
- BookmarkUpdate,
26
- } from './BookmarkClient.interface';
27
-
28
- import type { Bookmark, BookmarkData, BookmarkWithoutData, Bookmarks, BookmarkUser } from './types';
29
- import { bookmarkWithDataSchema } from './bookmark.schemas';
30
- import type { z } from 'zod';
31
-
32
- // Define the schema for the API response entity representing a bookmark
33
- const UserSchema = ApiPersonSchema['1.0'].transform((person) => {
34
- return {
35
- // @deprecated
36
- azureUniqueId: person.azureUniqueId,
37
- id: person.azureUniqueId,
38
- name: person.name,
39
- email: person.mail,
40
- } as BookmarkUser;
41
- });
42
-
43
- // Parse the bookmark entity from the API response
44
- const parseBookmark = <T extends BookmarkData>(value: unknown): Bookmark<T> => {
45
- const { createdBy, updatedBy, ...rest } = value as z.infer<
46
- (typeof ApiBookmarkSchema)[ApiVersion.v2]
47
- >;
48
- return bookmarkWithDataSchema().parse({
49
- ...rest,
50
- createdBy: UserSchema.parse(createdBy),
51
- updatedBy: updatedBy ? UserSchema.parse(updatedBy) : undefined,
52
- }) as Bookmark<T>;
53
- };
54
-
55
- const parseBookmarkWithoutPayload = (value: unknown): BookmarkWithoutData => {
56
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
57
- const { payload, ...bookmark } = parseBookmark(value);
58
- return bookmark;
59
- };
60
-
61
- /**
62
- * Represents a client for interacting with the Fusion Bookmarks API.
63
- * This class provides methods for retrieving, creating, updating, and deleting bookmarks, as well as managing favorites.
64
- *
65
- * This implementation consumes the `@equinor/fusion-framework-module-services/bookmarks` package.
66
- * This is the default implementation of the bookmarks API client.
67
- *
68
- * This class is intended to be used by the Fusion framework with the Fusion Core Services (Backend)
69
- *
70
- * Fetching single and all bookmarks will use Query from '@equinor/fusion-query' to cache the results.
71
- *
72
- * @remarks if you wish to implement your own bookmarks API client, you can do so by implementing the {@link IBookmarkClient} interface.
73
- */
74
- export class BookmarkClient implements IBookmarkClient {
75
- #api: BookmarksApiClient<'json$'>;
76
-
77
- #queryBookmark: Query<BookmarkWithoutData, { bookmarkId: string }>;
78
- #queryBookmarks: Query<Bookmarks, BookmarksFilter | undefined>;
79
- #queryBookmarkData: Query<BookmarkData | undefined, { bookmarkId: string }>;
80
-
81
- /**
82
- * Constructs a new `BookmarkClient` instance with the provided `BookmarksApiClient`.
83
- *
84
- * @param api - The `BookmarksApiClient` instance to use for making API requests.
85
- * @param options - Optional client options, such as the cache expiry time.
86
- */
87
- constructor(api: BookmarksApiClient<'json$'>, options?: { expire?: number }) {
88
- this.#api = api;
89
-
90
- const { expire = 5 * 60 * 1000 } = options ?? {};
91
-
92
- // set up the query for fetching a single bookmark
93
- this.#queryBookmark = new Query({
94
- client: {
95
- fn: (args: { bookmarkId: string }) => {
96
- // strip the payload from the fetched bookmark before caching
97
- return this.#api.get('v2', args).pipe(map(parseBookmarkWithoutPayload));
98
- },
99
- },
100
- key: (args) => args.bookmarkId,
101
- expire,
102
- });
103
-
104
- // set up the query for fetching all bookmarks
105
- this.#queryBookmarks = new Query({
106
- client: {
107
- fn: (filter?: BookmarksFilter) => {
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
- );
115
- },
116
- },
117
- key: (args) => JSON.stringify(args ?? ''),
118
- expire,
119
- });
120
-
121
- this.#queryBookmarkData = new Query({
122
- client: {
123
- fn: (args: { bookmarkId: string }) => {
124
- // extract only the payload from the API response
125
- return this.#api.getPayload('v1', args).pipe(map((res) => res.payload));
126
- },
127
- },
128
- key: (args) => args.bookmarkId,
129
- expire,
130
- cache: {
131
- trimming: {
132
- size: 3,
133
- },
134
- },
135
- });
136
- }
137
-
138
- /** @inheritdoc */
139
- public getAllBookmarks(filter?: BookmarksFilter): ObservableInput<Bookmark[]> {
140
- // unwrap the query result value
141
- return this.#queryBookmarks.query(filter).pipe(map((res) => res.value as Bookmark[]));
142
- }
143
-
144
- /** @inheritdoc */
145
- public getBookmarkById(bookmarkId: string): ObservableInput<BookmarkWithoutData> {
146
- // unwrap the query result value
147
- return this.#queryBookmark.query({ bookmarkId }).pipe(map((res) => res.value));
148
- }
149
-
150
- /** @inheritdoc */
151
- public getBookmarkData<T extends BookmarkData>(bookmarkId: string): ObservableInput<T> {
152
- // unwrap the query result value
153
- return this.#queryBookmarkData.query({ bookmarkId }).pipe(map((res): T => res.value as T));
154
- }
155
-
156
- /** @inheritdoc */
157
- public setBookmarkData<T extends BookmarkData | null>(
158
- bookmarkId: string,
159
- data: T,
160
- ): ObservableInput<T> {
161
- // update the payload cache once the mutation succeeds
162
- return this.#api.patch('v1', { bookmarkId, updates: { payload: data } }).pipe(
163
- map((res) => res.payload as T),
164
- tap((updatedData) => {
165
- // only update the cache when data was actually returned
166
- if (updatedData) {
167
- this.#queryBookmarkData.mutate(
168
- { bookmarkId },
169
- { value: updatedData, updated: Date.now() },
170
- { allowCreation: true },
171
- );
172
- }
173
- }),
174
- );
175
- }
176
-
177
- /** @inheritdoc */
178
- public createBookmark<T extends BookmarkData>(
179
- newBookmark: BookmarkNew<T>,
180
- ): ObservableInput<Bookmark<T>> {
181
- // parse the response and update caches once the bookmark is created
182
- return this.#api.create('v1', newBookmark).pipe(
183
- map((response) => parseBookmark<T>(response)),
184
- /** update the bookmark cache */
185
- tap((createdBookmark) => {
186
- console.log('createdBookmark', createdBookmark);
187
- const { payload, ...bookmark } = createdBookmark;
188
- this.#queryBookmark.mutate(
189
- { bookmarkId: bookmark.id },
190
- { value: bookmark, updated: Date.now() },
191
- { allowCreation: true },
192
- );
193
- // only cache the payload if the created bookmark has one
194
- if (payload) {
195
- this.#queryBookmarkData.mutate(
196
- { bookmarkId: bookmark.id },
197
- { value: payload, updated: Date.now() },
198
- { allowCreation: true },
199
- );
200
- }
201
- this.#queryBookmarks.invalidate();
202
- }),
203
- );
204
- }
205
-
206
- /** @inheritdoc */
207
- public updateBookmark<T extends BookmarkData>(
208
- bookmarkId: string,
209
- updates: BookmarkUpdate<T>,
210
- ): ObservableInput<Bookmark<T>> {
211
- // parse the response and share it across the cache-update subscriptions below
212
- const update$ = this.#api.patch('v1', { bookmarkId, updates: updates }).pipe(
213
- map((response) => parseBookmark<T>(response)),
214
- shareReplay(),
215
- );
216
- return new Observable((subscriber) => {
217
- // update the query cache for the specific bookmark
218
- subscriber.add(
219
- update$.subscribe((updatedBookmark) => {
220
- const { payload, ...bookmark } = updatedBookmark;
221
- // payload should not be included in the bookmark object
222
- payload;
223
- this.#queryBookmark.mutate(
224
- { bookmarkId },
225
- { value: bookmark, updated: Date.now() },
226
- { allowCreation: false },
227
- );
228
- }),
229
- );
230
-
231
- // update the cache for bookmark data
232
- subscriber.add(
233
- update$.subscribe((updatedBookmark) => {
234
- const { payload } = updatedBookmark;
235
- // only cache the payload when present, otherwise clear any stale cache entry
236
- if (payload) {
237
- this.#queryBookmarkData.mutate(
238
- {
239
- bookmarkId: updatedBookmark.id,
240
- },
241
- { value: payload, updated: Date.now() },
242
- { allowCreation: true },
243
- );
244
- } else {
245
- const cacheKey = this.#queryBookmarkData.generateCacheKey({
246
- bookmarkId: updatedBookmark.id,
247
- });
248
- this.#queryBookmarkData.cache.removeItem(cacheKey);
249
- }
250
- }),
251
- );
252
-
253
- // invalidate the bookmarks query cache
254
- subscriber.add(
255
- update$.subscribe(() => {
256
- this.#queryBookmarks.invalidate();
257
- }),
258
- );
259
-
260
- // emit the update to the subscriber
261
- update$.subscribe(subscriber);
262
- });
263
- }
264
-
265
- /** @inheritdoc */
266
- public deleteBookmark(bookmarkId: string): ObservableInput<boolean> {
267
- return this.#api.delete('v1', { bookmarkId });
268
- }
269
-
270
- /** @inheritdoc */
271
- public addBookmarkToFavorites(bookmarkId: string): ObservableInput<boolean> {
272
- // invalidate the bookmarks list cache once favorited
273
- return this.#api
274
- .addFavourite('v1', { bookmarkId })
275
- .pipe(tap(() => this.#queryBookmarks.invalidate()));
276
- }
277
-
278
- /** @inheritdoc */
279
- public removeBookmarkFromFavorites(bookmarkId: string): ObservableInput<boolean> {
280
- // invalidate the bookmarks list cache once unfavorited
281
- return this.#api
282
- .removeFavourite('v1', { bookmarkId })
283
- .pipe(tap(() => this.#queryBookmarks.invalidate()));
284
- }
285
-
286
- /** @inheritdoc */
287
- public isBookmarkFavorite(bookmarkId: string): ObservableInput<boolean> {
288
- return this.#api.isFavorite('v1', { bookmarkId });
289
- }
290
- }
@@ -1,38 +0,0 @@
1
- import type { ActionWithSuffix } from '@equinor/fusion-observable';
2
-
3
- import type { BookmarkActions } from './bookmark-actions';
4
-
5
- /**
6
- * Error thrown inside bookmark store flows (side-effect pipelines) when an
7
- * API call or observable chain fails.
8
- *
9
- * Carries a reference to the originating request action so callers can
10
- * correlate errors back to specific operations.
11
- */
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
- */
20
- constructor(
21
- message: string,
22
- /** The request action that triggered the failed flow. */
23
- public readonly action: ActionWithSuffix<BookmarkActions, 'request'>,
24
- options?: ErrorOptions,
25
- ) {
26
- super(message, options);
27
- this.name = 'BookmarkProcessError';
28
- }
29
- }
30
-
31
- /**
32
- * General-purpose error thrown by {@link BookmarkProvider} methods when a
33
- * high-level operation (create, update, delete, set current, etc.) fails.
34
- *
35
- * Distinct from {@link BookmarkFlowError}, which is scoped to internal
36
- * store flow pipelines.
37
- */
38
- export { BookmarkProviderError } from './BookmarkProviderError';