@equinor/fusion-framework-module-bookmark 1.2.13 → 2.0.0

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 (113) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +242 -9
  3. package/dist/esm/BookmarkClient.interface.js +2 -0
  4. package/dist/esm/BookmarkClient.interface.js.map +1 -0
  5. package/dist/esm/BookmarkClient.js +174 -0
  6. package/dist/esm/BookmarkClient.js.map +1 -0
  7. package/dist/esm/BookmarkConfigurator.js +348 -0
  8. package/dist/esm/BookmarkConfigurator.js.map +1 -0
  9. package/dist/esm/BookmarkProvider.actions.js +60 -0
  10. package/dist/esm/BookmarkProvider.actions.js.map +1 -0
  11. package/dist/esm/BookmarkProvider.error.js +14 -0
  12. package/dist/esm/BookmarkProvider.error.js.map +1 -0
  13. package/dist/esm/BookmarkProvider.events.js +2 -0
  14. package/dist/esm/BookmarkProvider.events.js.map +1 -0
  15. package/dist/esm/BookmarkProvider.flows.js +219 -0
  16. package/dist/esm/BookmarkProvider.flows.js.map +1 -0
  17. package/dist/esm/BookmarkProvider.js +937 -0
  18. package/dist/esm/BookmarkProvider.js.map +1 -0
  19. package/dist/esm/BookmarkProvider.reducer.js +125 -0
  20. package/dist/esm/BookmarkProvider.reducer.js.map +1 -0
  21. package/dist/esm/BookmarkProvider.selectors.js +43 -0
  22. package/dist/esm/BookmarkProvider.selectors.js.map +1 -0
  23. package/dist/esm/BookmarkProvider.store.js +19 -0
  24. package/dist/esm/BookmarkProvider.store.js.map +1 -0
  25. package/dist/esm/bookmark-config.schema.js +30 -0
  26. package/dist/esm/bookmark-config.schema.js.map +1 -0
  27. package/dist/esm/bookmark-module.js +53 -0
  28. package/dist/esm/bookmark-module.js.map +1 -0
  29. package/dist/esm/bookmark.schemas.js +38 -0
  30. package/dist/esm/bookmark.schemas.js.map +1 -0
  31. package/dist/esm/enable-bookmark.js +20 -7
  32. package/dist/esm/enable-bookmark.js.map +1 -1
  33. package/dist/esm/index.js +3 -3
  34. package/dist/esm/index.js.map +1 -1
  35. package/dist/esm/version.js +1 -1
  36. package/dist/esm/version.js.map +1 -1
  37. package/dist/tsconfig.tsbuildinfo +1 -1
  38. package/dist/types/BookmarkClient.d.ts +42 -0
  39. package/dist/types/BookmarkClient.interface.d.ts +139 -0
  40. package/dist/types/BookmarkConfigurator.d.ts +100 -0
  41. package/dist/types/BookmarkProvider.actions.d.ts +525 -0
  42. package/dist/types/BookmarkProvider.d.ts +462 -0
  43. package/dist/types/BookmarkProvider.error.d.ts +9 -0
  44. package/dist/types/BookmarkProvider.events.d.ts +78 -0
  45. package/dist/types/BookmarkProvider.flows.d.ts +79 -0
  46. package/dist/types/BookmarkProvider.reducer.d.ts +302 -0
  47. package/dist/types/BookmarkProvider.selectors.d.ts +34 -0
  48. package/dist/types/BookmarkProvider.store.d.ts +30 -0
  49. package/dist/types/bookmark-config.schema.d.ts +118 -0
  50. package/dist/types/{module.d.ts → bookmark-module.d.ts} +3 -3
  51. package/dist/types/bookmark.schemas.d.ts +760 -0
  52. package/dist/types/enable-bookmark.d.ts +7 -6
  53. package/dist/types/index.d.ts +4 -3
  54. package/dist/types/types.d.ts +29 -65
  55. package/dist/types/version.d.ts +1 -1
  56. package/package.json +11 -5
  57. package/src/BookmarkClient.interface.ts +157 -0
  58. package/src/BookmarkClient.ts +226 -0
  59. package/src/BookmarkConfigurator.ts +374 -0
  60. package/src/BookmarkProvider.actions.ts +131 -0
  61. package/src/BookmarkProvider.error.ts +21 -0
  62. package/src/BookmarkProvider.events.ts +89 -0
  63. package/src/BookmarkProvider.flows.ts +426 -0
  64. package/src/BookmarkProvider.reducer.ts +141 -0
  65. package/src/BookmarkProvider.selectors.ts +55 -0
  66. package/src/BookmarkProvider.store.ts +52 -0
  67. package/src/BookmarkProvider.ts +1308 -0
  68. package/src/bookmark-config.schema.ts +41 -0
  69. package/src/bookmark-module.ts +70 -0
  70. package/src/bookmark.schemas.ts +50 -0
  71. package/src/enable-bookmark.ts +13 -20
  72. package/src/index.ts +15 -7
  73. package/src/types.ts +46 -73
  74. package/src/version.ts +1 -1
  75. package/dist/esm/bookmark-config-builder.js +0 -131
  76. package/dist/esm/bookmark-config-builder.js.map +0 -1
  77. package/dist/esm/bookmark-provider.js +0 -155
  78. package/dist/esm/bookmark-provider.js.map +0 -1
  79. package/dist/esm/client/bookmarkActions.js +0 -10
  80. package/dist/esm/client/bookmarkActions.js.map +0 -1
  81. package/dist/esm/client/bookmarkClient.js +0 -259
  82. package/dist/esm/client/bookmarkClient.js.map +0 -1
  83. package/dist/esm/client/bookmarkFlows.js +0 -31
  84. package/dist/esm/client/bookmarkFlows.js.map +0 -1
  85. package/dist/esm/client/bookmarkReducer.js +0 -29
  86. package/dist/esm/client/bookmarkReducer.js.map +0 -1
  87. package/dist/esm/configurator.js +0 -155
  88. package/dist/esm/configurator.js.map +0 -1
  89. package/dist/esm/module.js +0 -27
  90. package/dist/esm/module.js.map +0 -1
  91. package/dist/esm/utils/handle-url.js +0 -11
  92. package/dist/esm/utils/handle-url.js.map +0 -1
  93. package/dist/esm/utils/index.js +0 -2
  94. package/dist/esm/utils/index.js.map +0 -1
  95. package/dist/types/bookmark-config-builder.d.ts +0 -85
  96. package/dist/types/bookmark-provider.d.ts +0 -169
  97. package/dist/types/client/bookmarkActions.d.ts +0 -27
  98. package/dist/types/client/bookmarkClient.d.ts +0 -53
  99. package/dist/types/client/bookmarkFlows.d.ts +0 -22
  100. package/dist/types/client/bookmarkReducer.d.ts +0 -5
  101. package/dist/types/configurator.d.ts +0 -75
  102. package/dist/types/utils/handle-url.d.ts +0 -2
  103. package/dist/types/utils/index.d.ts +0 -1
  104. package/src/bookmark-config-builder.ts +0 -177
  105. package/src/bookmark-provider.ts +0 -344
  106. package/src/client/bookmarkActions.ts +0 -44
  107. package/src/client/bookmarkClient.ts +0 -327
  108. package/src/client/bookmarkFlows.ts +0 -67
  109. package/src/client/bookmarkReducer.ts +0 -35
  110. package/src/configurator.ts +0 -235
  111. package/src/module.ts +0 -40
  112. package/src/utils/handle-url.ts +0 -13
  113. package/src/utils/index.ts +0 -1
@@ -0,0 +1,937 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
11
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
12
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
13
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
14
+ };
15
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
16
+ if (kind === "m") throw new TypeError("Private method is not writable");
17
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
18
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
19
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
20
+ };
21
+ var _BookmarkProvider_config, _BookmarkProvider_store, _BookmarkProvider_payloadGenerators, _BookmarkProvider_subscriptions;
22
+ import { Observable, Subscription, forkJoin, from, lastValueFrom, of } from 'rxjs';
23
+ import { filter, switchMap, tap, map, mergeScan, timeout, raceWith, first, catchError, } from 'rxjs/operators';
24
+ import { produce, enablePatches, castDraft } from 'immer';
25
+ import { v4 as generateGUID } from 'uuid';
26
+ import deepEqual from 'fast-deep-equal/es6';
27
+ import { FrameworkEvent } from '@equinor/fusion-framework-module-event';
28
+ import { isFailureAction } from '@equinor/fusion-observable';
29
+ import { SemanticVersion } from '@equinor/fusion-framework-module';
30
+ import { bookmarkActions } from './BookmarkProvider.actions';
31
+ import { createBookmarkStore } from './BookmarkProvider.store';
32
+ import { activeBookmarkSelector, bookmarkSelector, bookmarksSelector, errorsSelector, } from './BookmarkProvider.selectors';
33
+ import { BookmarkProviderError } from './BookmarkProvider.error';
34
+ import { version } from './version';
35
+ enablePatches();
36
+ const defaultTimeout = 2 * 60 * 1000; // 2 minutes
37
+ /**
38
+ * The `BookmarkProvider` class is responsible for managing bookmarks in the application.
39
+ * It provides methods for creating, updating, and removing bookmarks, as well as managing the current bookmark and the list of bookmarks.
40
+ *
41
+ * The `BookmarkProvider` uses a `BookmarkStore` to manage the state of the bookmarks, and an `IBookmarkClient` to interact with the backend API.
42
+ *
43
+ * The `BookmarkProvider` also supports event listeners for various bookmark-related events, such as when the current bookmark changes or when a bookmark is created, updated, or removed.
44
+ */
45
+ export class BookmarkProvider {
46
+ /**
47
+ * Gets the semantic version of the bookmark provider.
48
+ */
49
+ get version() {
50
+ return new SemanticVersion(version);
51
+ }
52
+ get filters() {
53
+ // TODO - freeze the config object?
54
+ return __classPrivateFieldGet(this, _BookmarkProvider_config, "f").filters;
55
+ }
56
+ /**
57
+ * Gets the `IBookmarkClient` instance used by this `BookmarkProvider`.
58
+ */
59
+ get client() {
60
+ return __classPrivateFieldGet(this, _BookmarkProvider_config, "f").client;
61
+ }
62
+ /**
63
+ * Gets the currently active bookmark (if any).
64
+ */
65
+ get currentBookmark$() {
66
+ return __classPrivateFieldGet(this, _BookmarkProvider_store, "f").select(activeBookmarkSelector, deepEqual);
67
+ }
68
+ /**
69
+ * Gets an observable that emits the current list of bookmarks.
70
+ */
71
+ get bookmarks$() {
72
+ this.getAllBookmarksAsync();
73
+ return __classPrivateFieldGet(this, _BookmarkProvider_store, "f").select(bookmarksSelector, deepEqual);
74
+ }
75
+ /**
76
+ * Gets the current list of bookmarks.
77
+ */
78
+ get bookmarks() {
79
+ return bookmarksSelector(__classPrivateFieldGet(this, _BookmarkProvider_store, "f").value);
80
+ }
81
+ /**
82
+ * Gets the currently active bookmark.
83
+ */
84
+ get currentBookmark() {
85
+ return activeBookmarkSelector(__classPrivateFieldGet(this, _BookmarkProvider_store, "f").value);
86
+ }
87
+ /**
88
+ * Represents an observable stream of the bookmark status.
89
+ */
90
+ get status$() {
91
+ return __classPrivateFieldGet(this, _BookmarkProvider_store, "f").select((x) => x.status);
92
+ }
93
+ /**
94
+ * Gets an observable that emits the current list of bookmark errors.
95
+ */
96
+ get errors$() {
97
+ // TODO - add deep diff
98
+ return __classPrivateFieldGet(this, _BookmarkProvider_store, "f").select(errorsSelector, deepEqual);
99
+ }
100
+ /**
101
+ * Determines whether there are any bookmark creators configured.
102
+ * `true` if there are any bookmark creators configured, `false` otherwise.
103
+ */
104
+ get hasBookmarkCreators() {
105
+ return __classPrivateFieldGet(this, _BookmarkProvider_payloadGenerators, "f").length > 0;
106
+ }
107
+ /**
108
+ * Gets the source system value from the configuration.
109
+ */
110
+ get sourceSystem() {
111
+ return __classPrivateFieldGet(this, _BookmarkProvider_config, "f").sourceSystem;
112
+ }
113
+ /**
114
+ * Gets the resolved application from the bookmark module configuration.
115
+ */
116
+ get resolvedApplication() {
117
+ return __classPrivateFieldGet(this, _BookmarkProvider_config, "f").resolve.application;
118
+ }
119
+ /**
120
+ * Gets the resolved context from the bookmark module configuration.
121
+ */
122
+ get resolvedContext() {
123
+ return __classPrivateFieldGet(this, _BookmarkProvider_config, "f").resolve.context;
124
+ }
125
+ get _apiClient() {
126
+ return __classPrivateFieldGet(this, _BookmarkProvider_config, "f").client;
127
+ }
128
+ /**
129
+ * configured logger instance.
130
+ */
131
+ get _log() {
132
+ return __classPrivateFieldGet(this, _BookmarkProvider_config, "f").log;
133
+ }
134
+ /**
135
+ * configured resolvers
136
+ */
137
+ get _resolve() {
138
+ return __classPrivateFieldGet(this, _BookmarkProvider_config, "f").resolve;
139
+ }
140
+ /**
141
+ * configured event provider.
142
+ */
143
+ get _event() {
144
+ return __classPrivateFieldGet(this, _BookmarkProvider_config, "f").eventProvider;
145
+ }
146
+ /**
147
+ * configured parent bookmark provider
148
+ */
149
+ get _parent() {
150
+ return __classPrivateFieldGet(this, _BookmarkProvider_config, "f").parent;
151
+ }
152
+ /**
153
+ * Constructs a new `BookmarkProvider` instance.
154
+ *
155
+ * @param config - The configuration for the bookmark module, including the client, initial state, and optional parent provider.
156
+ */
157
+ constructor(config) {
158
+ var _a, _b, _c;
159
+ /** provided configuration for the bookmark provider */
160
+ _BookmarkProvider_config.set(this, void 0);
161
+ /** state machine of the bookmark provider */
162
+ _BookmarkProvider_store.set(this, void 0);
163
+ /** collection of callback for creating bookmark payload */
164
+ _BookmarkProvider_payloadGenerators.set(this, []);
165
+ /** collection of subscriptions for bookmark events */
166
+ _BookmarkProvider_subscriptions.set(this, new Subscription());
167
+ __classPrivateFieldSet(this, _BookmarkProvider_config, config, "f");
168
+ __classPrivateFieldSet(this, _BookmarkProvider_store, createBookmarkStore({
169
+ client: config.client,
170
+ initial: { currentBookmark: (_b = (_a = this._parent) === null || _a === void 0 ? void 0 : _a.currentBookmark) !== null && _b !== void 0 ? _b : null },
171
+ }), "f");
172
+ // add teardown logic for disposing the store
173
+ __classPrivateFieldGet(this, _BookmarkProvider_subscriptions, "f").add(() => __classPrivateFieldGet(this, _BookmarkProvider_store, "f").complete());
174
+ // subscribe to the store actions and log them
175
+ __classPrivateFieldGet(this, _BookmarkProvider_subscriptions, "f").add(__classPrivateFieldGet(this, _BookmarkProvider_store, "f").action$.subscribe((action) => {
176
+ var _a, _b;
177
+ if (isFailureAction(action)) {
178
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.error(`Action: ${action.type}`, action);
179
+ }
180
+ else {
181
+ (_b = this._log) === null || _b === void 0 ? void 0 : _b.debug(`Action: ${action.type}`, action);
182
+ }
183
+ }));
184
+ // subscribe to the current bookmark changes and dispatch events
185
+ __classPrivateFieldGet(this, _BookmarkProvider_subscriptions, "f").add(__classPrivateFieldGet(this, _BookmarkProvider_store, "f").select(activeBookmarkSelector).subscribe((bookmark) => {
186
+ this._dispatchEvent('onCurrentBookmarkChanged', { detail: bookmark });
187
+ }));
188
+ // subscribe to child bookmark provider changes
189
+ // TODO - add support for disabling this feature
190
+ if (this._event) {
191
+ this._event.addEventListener('onCurrentBookmarkChanged', (event) => {
192
+ // only update the current bookmark if the event source is not this provider
193
+ if (event.source !== this) {
194
+ this.setCurrentBookmarkAsync(event.detail);
195
+ }
196
+ });
197
+ }
198
+ if (this._parent) {
199
+ // if a parent bookmark provider is configured, subscribe to its current bookmark changes
200
+ try {
201
+ __classPrivateFieldGet(this, _BookmarkProvider_subscriptions, "f").add(this._parent.currentBookmark$.subscribe((bookmark) => {
202
+ this.setCurrentBookmarkAsync(bookmark);
203
+ }));
204
+ }
205
+ catch (e) {
206
+ (_c = this._log) === null || _c === void 0 ? void 0 : _c.error('Failed to subscribe to parent bookmark provider', e);
207
+ }
208
+ }
209
+ }
210
+ /**
211
+ * Registers an event listener for the specified event on the BookmarkProvider.
212
+ *
213
+ * @param eventName - The name of the event to listen for. Must be a key of the `BookmarkProviderEventMap` type.
214
+ * @param callback - The callback function to be invoked when the event is triggered.
215
+ * The callback will receive the event object as its parameter, which will be of the type corresponding to the `eventName`.
216
+ * @returns A function that can be called to remove the event listener.
217
+ */
218
+ on(eventName, callback) {
219
+ var _a, _b;
220
+ if (!this._event) {
221
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.warn('Failed to register event listener, event provider not configured');
222
+ return () => { };
223
+ }
224
+ return (_b = this._event) === null || _b === void 0 ? void 0 : _b.addEventListener(eventName, callback);
225
+ }
226
+ /**
227
+ * Adds a new payload generator function to the BookmarkProvider.
228
+ * The payload generator function will be used to generate the payload for a bookmark-related action.
229
+ *
230
+ * @param fn - The payload generator function to add. It should be of type `PayloadGenerator<T>`, where `T` is the type of the bookmark data.
231
+ * @returns A function that can be called to remove the added payload generator.
232
+ */
233
+ addPayloadGenerator(fn) {
234
+ var _a;
235
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`adding bookmark payload generator: ${fn.name}`);
236
+ // register the payload generator function
237
+ __classPrivateFieldGet(this, _BookmarkProvider_payloadGenerators, "f").push(fn);
238
+ // dispatch event to notify listeners of the added payload generator
239
+ this._dispatchEvent('onBookmarkPayloadCreatorAdded', {
240
+ detail: fn,
241
+ });
242
+ // return a function to remove the added payload generator
243
+ return () => {
244
+ var _a;
245
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`removing bookmark payload generator: ${fn.name}`);
246
+ __classPrivateFieldSet(this, _BookmarkProvider_payloadGenerators, __classPrivateFieldGet(this, _BookmarkProvider_payloadGenerators, "f").filter((g) => g !== fn), "f");
247
+ };
248
+ }
249
+ /**
250
+ * Generates a payload by applying registered generator functions to an accumulator object.
251
+ *
252
+ * @param initial - The initial value of the accumulator object.
253
+ * @returns An observable that emits the generated payload.
254
+ * @template T - The type of the generated payload.
255
+ */
256
+ generatePayload(initial) {
257
+ var _a;
258
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`generating payload`, initial);
259
+ /**
260
+ * Generates a payload by applying a generator function to an accumulator object.
261
+ * The generator function can modify the accumulator object using immer's draft mechanism.
262
+ *
263
+ * @param acc - The accumulator object.
264
+ * @param generator - The generator function that modifies the accumulator object.
265
+ * @returns A promise that resolves to the generated payload.
266
+ */
267
+ const generatePayload = (acc, generator) => __awaiter(this, void 0, void 0, function* () {
268
+ // produce payload from generator
269
+ return produce(acc, (draft) => __awaiter(this, void 0, void 0, function* () {
270
+ var _a, _b;
271
+ // execute the generator
272
+ const result = yield Promise.resolve(generator(draft, initial));
273
+ if (result) {
274
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.warn(`bookmark data generator ${generator.name} returned a value, but it should not do this, since the data is an immer draft object`);
275
+ return castDraft(result);
276
+ }
277
+ else if (result === null) {
278
+ (_b = this._log) === null || _b === void 0 ? void 0 : _b.info(`bookmark data generator ${generator.name} wish to clear the bookmark data`);
279
+ return null;
280
+ }
281
+ }), (patches) => {
282
+ var _a;
283
+ if (patches.length > 0) {
284
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`bookmark data generator ${generator.name} produced patches`, patches);
285
+ }
286
+ });
287
+ });
288
+ /**
289
+ * Observable that emits the generated payload.
290
+ */
291
+ const result$ = from(__classPrivateFieldGet(this, _BookmarkProvider_payloadGenerators, "f")).pipe(mergeScan(generatePayload, initial !== null && initial !== void 0 ? initial : {}, 1), tap((payload) => { var _a; return (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`generated payload`, { initial, payload }); }));
292
+ return result$;
293
+ }
294
+ /**
295
+ * Retrieves a bookmark with the specified bookmarkId and returns an observable that emits the combined result of fetching the bookmark and bookmark data.
296
+ * @template T The type of the bookmark payload.
297
+ * @param bookmarkId The unique identifier of the bookmark.
298
+ * @param options An optional object that allows excluding the bookmark payload from the result.
299
+ * @returns An observable that emits the combined result of fetching the bookmark and bookmark data.
300
+ */
301
+ getBookmark(bookmarkId, options) {
302
+ var _a;
303
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`fetching bookmark: ${bookmarkId}`, options);
304
+ // fetch the bookmark and bookmark data
305
+ return forkJoin({
306
+ bookmark: this._getBookmarkInfo(bookmarkId),
307
+ payload: (options === null || options === void 0 ? void 0 : options.excludePayload) ? of({}) : this._getBookmarkData(bookmarkId),
308
+ }).pipe(catchError((error) => {
309
+ var _a;
310
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.error(`Failed to fetch bookmark: ${bookmarkId}`, error);
311
+ throw error;
312
+ }),
313
+ // combine the bookmark and payload into a single object
314
+ map(({ bookmark, payload }) => Object.assign({}, bookmark, { payload })), tap((bookmark) => {
315
+ var _a;
316
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`Bookmark fetched: ${bookmark.id}`, bookmark);
317
+ }));
318
+ }
319
+ /**
320
+ * Retrieves a bookmark asynchronously.
321
+ *
322
+ * @param id - The ID of the bookmark to retrieve.
323
+ * @param options - Optional parameters for the retrieval.
324
+ * @param options.excludePayload - Specifies whether to exclude the payload from the bookmark.
325
+ * @returns A promise that resolves to the retrieved bookmark, or null if the bookmark is not found.
326
+ */
327
+ getBookmarkAsync(id, options) {
328
+ return lastValueFrom(this.getBookmark(id, options));
329
+ }
330
+ /**
331
+ * Asynchronously retrieves all bookmarks from the store.
332
+ *
333
+ * @returns A Promise that resolves to the Bookmarks object containing all bookmarks.
334
+ */
335
+ getAllBookmarks() {
336
+ return new Observable((observer) => {
337
+ var _a, _b, _c;
338
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`fetching all bookmarks`);
339
+ // generate the filter parameters
340
+ const filter$ = forkJoin({
341
+ sourceSystem: of(this.sourceSystem),
342
+ appKey: ((_b = __classPrivateFieldGet(this, _BookmarkProvider_config, "f").filters) === null || _b === void 0 ? void 0 : _b.application)
343
+ ? from(this._resolve.application()).pipe(map((x) => x === null || x === void 0 ? void 0 : x.appKey))
344
+ : of(undefined),
345
+ contextId: ((_c = __classPrivateFieldGet(this, _BookmarkProvider_config, "f").filters) === null || _c === void 0 ? void 0 : _c.context)
346
+ ? from(this._resolve.context()).pipe(map((x) => x === null || x === void 0 ? void 0 : x.id))
347
+ : of(undefined),
348
+ }).pipe(catchError((err) => {
349
+ var _a;
350
+ const error = new BookmarkProviderError('Could not fetch bookmarks, failed to resolve filter parameters', err);
351
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.error(error.message, error);
352
+ throw error;
353
+ }));
354
+ // execute the fetch bookmarks action when the filter parameters are resolved
355
+ observer.add(filter$.subscribe((filter) => {
356
+ __classPrivateFieldGet(this, _BookmarkProvider_store, "f").next(bookmarkActions.fetchBookmarks(filter));
357
+ }));
358
+ // monitor the failure case when fetching bookmarks
359
+ const failure$ = __classPrivateFieldGet(this, _BookmarkProvider_store, "f").action$.pipe(filter(bookmarkActions.fetchBookmarks.failure.match), map((action) => {
360
+ var _a;
361
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.error('Failed to fetch bookmarks', action.payload);
362
+ throw new BookmarkProviderError('Failed to fetch bookmarks', action.payload);
363
+ }), timeout({
364
+ each: defaultTimeout,
365
+ with: () => {
366
+ throw new BookmarkProviderError('Timeout while fetching bookmarks');
367
+ },
368
+ }));
369
+ // monitor the success case when fetching bookmarks
370
+ const request$ = __classPrivateFieldGet(this, _BookmarkProvider_store, "f").action$.pipe(filter(bookmarkActions.fetchBookmarks.success.match), map((a) => a.payload), first(), tap((bookmarks) => {
371
+ var _a;
372
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`fetched all bookmarks`, bookmarks);
373
+ }), raceWith(failure$));
374
+ request$.subscribe(observer);
375
+ });
376
+ }
377
+ /**
378
+ * Asynchronously retrieves all bookmarks from the store.
379
+ *
380
+ * @returns A Promise that resolves to the Bookmarks object containing all bookmarks.
381
+ */
382
+ getAllBookmarksAsync() {
383
+ return __awaiter(this, void 0, void 0, function* () {
384
+ return lastValueFrom(this.getAllBookmarks());
385
+ });
386
+ }
387
+ /**
388
+ * Sets the current bookmark to the specified bookmark or ID.
389
+ * If the bookmark is already the current bookmark, it returns the bookmark directly.
390
+ * Otherwise, it emits the next bookmark or null through an observable.
391
+ *
392
+ * By proving `null` as the bookmark_or_id, the current bookmark will be cleared.
393
+ *
394
+ * @param bookmark_or_id - The bookmark or ID to set as the current bookmark.
395
+ * @returns An observable that emits the next bookmark or null.
396
+ * @template T - The type of the bookmark data.
397
+ */
398
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
399
+ setCurrentBookmark(bookmark_or_id) {
400
+ var _a;
401
+ // check if the bookmark is already the current bookmark
402
+ if (bookmark_or_id == this.currentBookmark)
403
+ return of(bookmark_or_id);
404
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`setting current bookmark`, bookmark_or_id);
405
+ // resolve the next bookmark
406
+ const next$ = typeof bookmark_or_id === 'string'
407
+ ? this.getBookmark(bookmark_or_id)
408
+ : of(bookmark_or_id !== null && bookmark_or_id !== void 0 ? bookmark_or_id : null);
409
+ return next$.pipe(switchMap((next) => __awaiter(this, void 0, void 0, function* () {
410
+ var _a, _b, _c;
411
+ const current = this.currentBookmark;
412
+ const { type, canceled } = yield this._dispatchEvent('onCurrentBookmarkChange', {
413
+ detail: { current, next },
414
+ });
415
+ if (canceled) {
416
+ const error = new BookmarkProviderError(`event: ${type} was canceled by listener for change to ${(_a = next === null || next === void 0 ? void 0 : next.id) !== null && _a !== void 0 ? _a : 'none'}, from ${(_b = current === null || current === void 0 ? void 0 : current.id) !== null && _b !== void 0 ? _b : 'none'}`);
417
+ (_c = this._log) === null || _c === void 0 ? void 0 : _c.info(error.message);
418
+ throw error;
419
+ }
420
+ return next;
421
+ })), tap((next) => {
422
+ // set the current bookmark in the store
423
+ __classPrivateFieldGet(this, _BookmarkProvider_store, "f").next(bookmarkActions.setCurrentBookmark(next));
424
+ }), catchError((err) => {
425
+ var _a;
426
+ const error = new BookmarkProviderError('Could not set current bookmark, resolve of bookmark failed', err);
427
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.error(error.message, error);
428
+ throw error;
429
+ }));
430
+ }
431
+ /**
432
+ * Sets the current bookmark.
433
+ * This method dispatches an event to notify listeners of a change in the current bookmark,
434
+ * and then dispatches a request to set the active bookmark in the application state.
435
+ *
436
+ * The request will be canceled if the subscription is unsubscribed before the request completes.
437
+ *
438
+ * @param bookmarkId - The ID of the bookmark to set as the current bookmark.
439
+ * @returns A subscription to the operation that sets the current bookmark.
440
+ */
441
+ setCurrentBookmarkAsync(bookmark_or_id) {
442
+ return lastValueFrom(this.setCurrentBookmark(bookmark_or_id));
443
+ }
444
+ /**
445
+ * Creates a new bookmark with the provided bookmark data.
446
+ * @template T - The type of bookmark data.
447
+ * @param {BookmarkCreateArgs<T>} newBookmarkData - The data for creating the bookmark.
448
+ * @returns {Observable<Bookmark<T>>} - An observable that emits the created bookmark.
449
+ */
450
+ createBookmark(newBookmarkData) {
451
+ return new Observable((subscriber) => {
452
+ var _a;
453
+ const { ref, action$ } = this._useScopedActions();
454
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`creating new bookmark, ref: ${ref}`, newBookmarkData);
455
+ // resolve the bookmark
456
+ const bookmark$ = forkJoin({
457
+ appKey: newBookmarkData.appKey
458
+ ? of(newBookmarkData.appKey)
459
+ : from(this._resolve.application()).pipe(map((app) => {
460
+ if (!(app === null || app === void 0 ? void 0 : app.appKey)) {
461
+ throw new BookmarkProviderError('Failed to resolve application key');
462
+ }
463
+ return app.appKey;
464
+ })),
465
+ contextId: this._resolve.context().then((context) => context === null || context === void 0 ? void 0 : context.id),
466
+ payload: this.generatePayload(newBookmarkData.payload),
467
+ sourceSystem: of(this.sourceSystem),
468
+ }).pipe(catchError((err) => {
469
+ var _a;
470
+ const error = new BookmarkProviderError('Could not create new bookmark, failed to resolve bookmark data', err);
471
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.error(error.message, error);
472
+ throw error;
473
+ }),
474
+ // merge the resolved data with the new bookmark data
475
+ map((resolvedData) => (Object.assign(Object.assign({}, newBookmarkData), resolvedData))));
476
+ // notify listeners that a bookmark is about to be created
477
+ const dispatch$ = bookmark$.pipe(switchMap((bookmark) => __awaiter(this, void 0, void 0, function* () {
478
+ var _a;
479
+ // notify listeners that a bookmark is about to be created
480
+ const { canceled, type } = yield this._dispatchEvent('onBookmarkCreate', {
481
+ detail: bookmark,
482
+ cancelable: true,
483
+ });
484
+ // throw an error if the event is canceled
485
+ if (canceled) {
486
+ const error = new BookmarkProviderError(`event: ${type} was canceled by listener for creating bookmark: ${ref}`);
487
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.info(error.message);
488
+ throw error;
489
+ }
490
+ return bookmark;
491
+ })));
492
+ // execute the create bookmark action when the bookmark is resolved and not canceled
493
+ subscriber.add(dispatch$.subscribe({
494
+ error: (error) => subscriber.error(error),
495
+ next: (newBookmark) => {
496
+ // request the store to create the bookmark
497
+ __classPrivateFieldGet(this, _BookmarkProvider_store, "f").next(bookmarkActions.createBookmark(newBookmark, { ref }));
498
+ },
499
+ }));
500
+ // monitor the failure case when creating a bookmark
501
+ const failure$ = action$.pipe(filter(bookmarkActions.createBookmark.failure.match), map(({ payload: cause }) => {
502
+ var _a;
503
+ const error = new BookmarkProviderError(`Failed to create bookmark: ${ref}`, {
504
+ cause,
505
+ });
506
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.warn(error.message);
507
+ throw error;
508
+ }), timeout({
509
+ each: defaultTimeout,
510
+ with: () => {
511
+ throw new BookmarkProviderError(`Timeout while creating bookmark: ${ref}`);
512
+ },
513
+ }));
514
+ // monitor the success case when creating a bookmark
515
+ const request$ = action$.pipe(filter(bookmarkActions.createBookmark.success.match), map(({ payload }) => payload), first(), tap((bookmark) => {
516
+ var _a;
517
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.info(`Bookmark created: ${bookmark.id}, ref: ${ref}`);
518
+ this._dispatchEvent('onBookmarkCreated', { detail: bookmark });
519
+ }), raceWith(failure$));
520
+ // emit the created bookmark
521
+ request$.subscribe(subscriber);
522
+ });
523
+ }
524
+ /**
525
+ * Asynchronously creates a new bookmark.
526
+ *
527
+ * @param bookmark - The new bookmark to create.
528
+ * @returns A promise that resolves to the created bookmark with its associated data.
529
+ */
530
+ createBookmarkAsync(args) {
531
+ return lastValueFrom(this.createBookmark(args));
532
+ }
533
+ /**
534
+ * Updates a bookmark with the specified bookmarkId and bookmarkUpdates.
535
+ *
536
+ * @template T - The type of the bookmark data.
537
+ * @param {string} bookmarkId - The identifier of the bookmark to update.
538
+ * @param {BookmarkUpdate<T>} [bookmarkUpdates] - The updates to apply to the bookmark.
539
+ * @param {BookmarkUpdateOptions} [options] - The options for updating the bookmark.
540
+ * @returns {Promise<Bookmark<T>>} - A promise that resolves to the updated bookmark.
541
+ */
542
+ updateBookmark(bookmarkId, bookmarkUpdates, options) {
543
+ if (!bookmarkUpdates && (options === null || options === void 0 ? void 0 : options.excludePayloadGeneration)) {
544
+ throw new BookmarkProviderError('Cannot update bookmark without updates and excludePayloadGeneration option');
545
+ }
546
+ return new Observable((subscriber) => {
547
+ var _a;
548
+ const { ref, action$ } = this._useScopedActions();
549
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`Updating bookmark: ${bookmarkId}, ref: ${ref}`);
550
+ /**
551
+ * Generate updates with payload
552
+ * @remarks
553
+ * If `excludePayloadGeneration` is `true`, it emits the `bookmarkUpdates` directly.
554
+ * If `excludePayloadGeneration` is `false`, it generates the payload using the `generatePayload` method and emits the updated `bookmarkUpdates` with the generated payload.
555
+ */
556
+ const updates$ = (options === null || options === void 0 ? void 0 : options.excludePayloadGeneration)
557
+ ? of(bookmarkUpdates)
558
+ : this.generatePayload(bookmarkUpdates === null || bookmarkUpdates === void 0 ? void 0 : bookmarkUpdates.payload).pipe(map((payload) => (Object.assign(Object.assign({}, bookmarkUpdates), { payload }))));
559
+ // notify listeners that a bookmark is about to be updated
560
+ const dispatch$ = updates$.pipe(switchMap((updates) => __awaiter(this, void 0, void 0, function* () {
561
+ var _a;
562
+ const { canceled, type } = yield this._dispatchEvent('onBookmarkUpdate', {
563
+ detail: {
564
+ current: bookmarkSelector(__classPrivateFieldGet(this, _BookmarkProvider_store, "f").value, bookmarkId),
565
+ updates,
566
+ },
567
+ cancelable: true,
568
+ });
569
+ if (canceled) {
570
+ const error = new BookmarkProviderError(`event: ${type} was canceled by listener for updating bookmark: ${bookmarkId}, ref: ${ref}`);
571
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.warn(error.message, updates);
572
+ throw error;
573
+ }
574
+ return updates;
575
+ })));
576
+ // execute the update bookmark action when the updates are resolved and not canceled
577
+ subscriber.add(dispatch$.subscribe({
578
+ error: (error) => subscriber.error(error),
579
+ next: (updates) => {
580
+ // trigger the store to update the bookmark
581
+ __classPrivateFieldGet(this, _BookmarkProvider_store, "f").next(bookmarkActions.updateBookmark({ bookmarkId, updates }, { ref }));
582
+ },
583
+ }));
584
+ // monitor the failure case when updating a bookmark
585
+ const failure$ = action$.pipe(filter(bookmarkActions.updateBookmark.failure.match), map(({ payload: cause }) => {
586
+ var _a;
587
+ const error = new BookmarkProviderError(`Failed to update bookmark: ${bookmarkId}`, {
588
+ cause,
589
+ });
590
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.info(error.message);
591
+ throw error;
592
+ }), timeout({
593
+ each: defaultTimeout,
594
+ with: () => {
595
+ throw new BookmarkProviderError(`Timeout while updating bookmark: ${bookmarkId}`);
596
+ },
597
+ }));
598
+ // monitor the success case when updating a bookmark
599
+ const request$ = action$.pipe(filter(bookmarkActions.updateBookmark.success.match), first(), map(
600
+ // TODO: add payload if current bookmark is the same as the updated bookmark
601
+ ({ payload }) => (Object.assign(Object.assign({}, bookmarkSelector(__classPrivateFieldGet(this, _BookmarkProvider_store, "f").value, payload.id)), { payload: payload.payload }))), tap((bookmark) => {
602
+ var _a;
603
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.info(`Bookmark updated: ${bookmark.id}, ref: ${ref}`);
604
+ this._dispatchEvent('onBookmarkUpdated', { detail: bookmark });
605
+ }), raceWith(failure$));
606
+ // emit the updated bookmark
607
+ request$.subscribe(subscriber);
608
+ });
609
+ }
610
+ /**
611
+ * Updates a bookmark asynchronously.
612
+ *
613
+ * @param bookmark - The bookmark to update.
614
+ * @returns A promise that resolves to the updated bookmark with its associated data.
615
+ */
616
+ updateBookmarkAsync(bookmarkId, bookmarkUpdates, options) {
617
+ return lastValueFrom(this.updateBookmark(bookmarkId, bookmarkUpdates, options));
618
+ }
619
+ /**
620
+ * Deletes a bookmark with the specified bookmarkId.
621
+ *
622
+ * @param bookmarkId - The unique identifier of the bookmark to be deleted.
623
+ * @returns A Promise that resolves when the bookmark is successfully deleted.
624
+ * @throws {BookmarkProviderError} If there is an error deleting the bookmark.
625
+ */
626
+ deleteBookmark(bookmarkId) {
627
+ return new Observable((subscriber) => {
628
+ var _a, _b;
629
+ const { ref, action$ } = this._useScopedActions();
630
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`Removing bookmark: ${bookmarkId}, ref: ${ref}`);
631
+ // bookmark to delete
632
+ const bookmark = (_b = bookmarkSelector(__classPrivateFieldGet(this, _BookmarkProvider_store, "f").value, bookmarkId)) !== null && _b !== void 0 ? _b : {
633
+ id: bookmarkId,
634
+ };
635
+ // observable that dispatches the 'onBookmarkDelete' event and maps the result
636
+ const dispatch$ = from(this._dispatchEvent('onBookmarkDelete', {
637
+ detail: bookmark,
638
+ cancelable: true,
639
+ })).pipe(map(({ canceled, type, detail }) => {
640
+ var _a;
641
+ if (canceled) {
642
+ const error = new BookmarkProviderError(`event: ${type} was canceled by listener for removing bookmark: ${bookmarkId}, ref: ${ref}`);
643
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.warn(error.message);
644
+ throw error;
645
+ }
646
+ return detail;
647
+ }));
648
+ // execute the delete bookmark action when the event is not canceled
649
+ subscriber.add(dispatch$.subscribe({
650
+ error: (error) => subscriber.error(error),
651
+ next: (bookmark) => {
652
+ // request the store to delete the bookmark
653
+ __classPrivateFieldGet(this, _BookmarkProvider_store, "f").next(bookmarkActions.deleteBookmark(bookmark.id, { ref }));
654
+ },
655
+ }));
656
+ // monitor the failure case when deleting a bookmark
657
+ const failure$ = action$.pipe(filter(bookmarkActions.deleteBookmark.failure.match), map(({ payload: cause }) => {
658
+ var _a;
659
+ const error = new BookmarkProviderError(`Failed to update bookmark: ${bookmarkId}`, {
660
+ cause,
661
+ });
662
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.warn(error.message);
663
+ throw error;
664
+ }), timeout({
665
+ each: defaultTimeout,
666
+ with: () => {
667
+ throw new BookmarkProviderError(`Timeout while updating bookmark: ${bookmarkId}`);
668
+ },
669
+ }));
670
+ // monitor the success case when deleting a bookmark
671
+ const request$ = action$.pipe(filter(bookmarkActions.deleteBookmark.success.match), map(() => undefined), first(), tap(() => {
672
+ var _a;
673
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.info(`Removed bookmark: ${bookmark.id}, ref: ${ref}`);
674
+ this._dispatchEvent('onBookmarkDeleted', { detail: bookmark });
675
+ }), raceWith(failure$));
676
+ // emit the deleted bookmark
677
+ request$.subscribe(subscriber);
678
+ });
679
+ }
680
+ /**
681
+ * Deletes a bookmark asynchronously.
682
+ *
683
+ * @param bookmarkId - The ID of the bookmark to delete.
684
+ * @returns A Promise that resolves when the bookmark is deleted.
685
+ */
686
+ deleteBookmarkAsync(bookmarkId) {
687
+ return __awaiter(this, void 0, void 0, function* () {
688
+ return lastValueFrom(this.deleteBookmark(bookmarkId));
689
+ });
690
+ }
691
+ /**
692
+ * Adds a bookmark to the favorites.
693
+ *
694
+ * @param bookmarkId - The ID of the bookmark to add.
695
+ * @returns A Promise that resolves to the added bookmark, or null if the bookmark was not added.
696
+ */
697
+ addBookmarkToFavorites(bookmarkId) {
698
+ /**
699
+ * Observable that represents the result of adding a bookmark as a favorite.
700
+ * Emits a `Bookmark` object or `undefined` if the operation fails to resolve added bookmark.
701
+ */
702
+ const result$ = new Observable((subscriber) => {
703
+ var _a;
704
+ const { ref, action$ } = this._useScopedActions();
705
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`Adding bookmark: ${bookmarkId} to favourites, ref: ${ref}`);
706
+ // observable that dispatches the 'onBookmarkFavouriteAdd' event and maps the result
707
+ const dispatch$ = from(this._dispatchEvent('onBookmarkFavouriteAdd', {
708
+ detail: { id: bookmarkId },
709
+ cancelable: true,
710
+ })).pipe(map(({ canceled, type }) => {
711
+ var _a;
712
+ if (canceled) {
713
+ const error = new BookmarkProviderError(`event: ${type} was canceled by listener for adding favourite bookmark: ${bookmarkId}, ref: ${ref}`);
714
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.info(error.message);
715
+ throw error;
716
+ }
717
+ }));
718
+ // execute the add bookmark as a favorite action when the event is not canceled
719
+ subscriber.add(dispatch$.subscribe({
720
+ error: (error) => subscriber.error(error),
721
+ next: () => {
722
+ __classPrivateFieldGet(this, _BookmarkProvider_store, "f").next(bookmarkActions.addBookmarkAsFavourite(bookmarkId, { ref }));
723
+ },
724
+ }));
725
+ // monitor the failure case when adding a bookmark as a favorite
726
+ const failure$ = action$.pipe(filter(bookmarkActions.addBookmarkAsFavourite.failure.match), map(({ payload: cause }) => {
727
+ var _a;
728
+ const error = new BookmarkProviderError(`Failed to add bookmark to favorites: ${bookmarkId}`, { cause });
729
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.warn(error.message);
730
+ throw error;
731
+ }), timeout({
732
+ each: defaultTimeout,
733
+ with: () => {
734
+ throw new BookmarkProviderError(`Timeout while adding bookmark to favorites: ${bookmarkId}`);
735
+ },
736
+ }));
737
+ // monitor the success case when adding a bookmark as a favorite
738
+ const request$ = action$.pipe(filter(bookmarkActions.addBookmarkAsFavourite.success.match), switchMap(({ payload }) => this.getBookmark(payload, { excludePayload: true })), tap((bookmark) => {
739
+ var _a;
740
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.info(`Added bookmark: ${bookmarkId} to favourites, ref: ${ref}`);
741
+ this._dispatchEvent('onBookmarkFavouriteAdded', { detail: bookmark });
742
+ }), raceWith(failure$));
743
+ // emit the added bookmark
744
+ return request$.subscribe(subscriber);
745
+ });
746
+ return result$;
747
+ }
748
+ /**
749
+ * Asynchronously adds a bookmark to the user's favorites.
750
+ *
751
+ * @param bookmarkId - The ID of the bookmark to add to the user's favorites.
752
+ * @returns A Promise that resolves to the added Bookmark, or null if the operation failed.
753
+ */
754
+ addBookmarkToFavoritesAsync(bookmarkId) {
755
+ return lastValueFrom(this.addBookmarkToFavorites(bookmarkId));
756
+ }
757
+ /**
758
+ * Removes a bookmark as a favorite.
759
+ *
760
+ * @param bookmarkId - The ID of the bookmark to remove as a favorite.
761
+ * @returns A Promise that resolves when the bookmark is successfully removed as a favorite.
762
+ * @throws {BookmarkProviderError} If the event is canceled or if there is a failure in removing the bookmark as a favorite.
763
+ */
764
+ removeBookmarkAsFavorite(bookmarkId) {
765
+ /**
766
+ * Represents an observable that emits void values when a bookmark's favorite is removed.
767
+ */
768
+ const result$ = new Observable((subscriber) => {
769
+ var _a, _b;
770
+ const { ref, action$ } = this._useScopedActions();
771
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`Removing bookmark: ${bookmarkId} from favourites, ref: ${ref}`);
772
+ // get the bookmark to remove as a favorite
773
+ const bookmark = (_b = bookmarkSelector(__classPrivateFieldGet(this, _BookmarkProvider_store, "f").value, bookmarkId)) !== null && _b !== void 0 ? _b : { id: bookmarkId };
774
+ // observable that dispatches the 'onBookmarkFavouriteRemove' event and maps the result
775
+ const dispatch$ = from(this._dispatchEvent('onBookmarkFavouriteRemove', {
776
+ detail: bookmark,
777
+ cancelable: true,
778
+ })).pipe(map(({ canceled, type, detail }) => {
779
+ var _a;
780
+ if (canceled) {
781
+ const error = new BookmarkProviderError(`event: ${type} was canceled by listener for removing favourite bookmark: ${bookmarkId}, ref: ${ref}`);
782
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.warn(error.message);
783
+ throw error;
784
+ }
785
+ return detail;
786
+ }));
787
+ // execute the remove bookmark as a favorite action when the event is not canceled
788
+ subscriber.add(dispatch$.subscribe({
789
+ error: (error) => subscriber.error(error),
790
+ next: (detail) => {
791
+ // request the store to remove the bookmark as a favorite
792
+ __classPrivateFieldGet(this, _BookmarkProvider_store, "f").next(bookmarkActions.removeBookmarkAsFavourite(detail.id, { ref }));
793
+ },
794
+ }));
795
+ // monitor the failure case when removing a bookmark as a favorite
796
+ const failure$ = action$.pipe(filter(bookmarkActions.removeBookmarkAsFavourite.failure.match), map(({ payload: cause }) => {
797
+ var _a;
798
+ const error = new BookmarkProviderError(`Failed to remove bookmark: ${bookmarkId} from favourites`, {
799
+ cause,
800
+ });
801
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.warn(error.message);
802
+ throw error;
803
+ }), timeout({
804
+ each: defaultTimeout,
805
+ with: () => {
806
+ throw new BookmarkProviderError(`Timeout while removing bookmark: ${bookmarkId} from favourites`);
807
+ },
808
+ }));
809
+ // monitor the success case when removing a bookmark as a favorite
810
+ const request$ = action$.pipe(filter(bookmarkActions.removeBookmarkAsFavourite.success.match), tap(() => {
811
+ var _a;
812
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.info(`Removed bookmark: ${bookmarkId} from favourites, ref: ${ref}`);
813
+ this._dispatchEvent('onBookmarkFavouriteRemoved', { detail: bookmark });
814
+ }), map(() => { }), raceWith(failure$));
815
+ // emit the removed bookmark
816
+ request$.subscribe(subscriber);
817
+ });
818
+ return result$;
819
+ }
820
+ /**
821
+ * Removes a bookmark as a favorite asynchronously.
822
+ *
823
+ * @param bookmarkId - The ID of the bookmark to remove as a favorite.
824
+ * @returns A Promise that resolves when the bookmark is successfully removed as a favorite.
825
+ */
826
+ removeBookmarkAsFavoriteAsync(bookmarkId) {
827
+ return lastValueFrom(this.removeBookmarkAsFavorite(bookmarkId));
828
+ }
829
+ /**
830
+ * Checks if a bookmark is in the favorites.
831
+ * @param bookmarkId - The ID of the bookmark to check.
832
+ * @returns A promise that resolves to a boolean indicating whether the bookmark is in the favorites.
833
+ */
834
+ isBookmarkInFavorites(bookmarkId) {
835
+ var _a;
836
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`Checking if bookmark: ${bookmarkId} is in favourites`);
837
+ // Check if the bookmark is a favorite
838
+ return from(this._apiClient.isBookmarkFavorite(bookmarkId)).pipe(catchError((err) => {
839
+ var _a;
840
+ const error = new BookmarkProviderError(`Failed to check if bookmark: ${bookmarkId} is in favourites`, err);
841
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.error(error.message, error);
842
+ throw error;
843
+ }), tap((isFavorite) => {
844
+ var _a;
845
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`Bookmark: ${bookmarkId} is ${isFavorite ? 'in' : 'not in'} favourites`);
846
+ }));
847
+ }
848
+ /**
849
+ * Checks if the specified bookmark is in the user's favorites.
850
+ *
851
+ * @param bookmarkId - The ID of the bookmark to check.
852
+ * @returns A Promise that resolves to a boolean indicating whether the bookmark is in the user's favorites.
853
+ */
854
+ isBookmarkInFavoritesAsync(bookmarkId) {
855
+ return lastValueFrom(this.isBookmarkInFavorites(bookmarkId));
856
+ }
857
+ _getBookmarkInfo(bookmarkId, options) {
858
+ var _a;
859
+ // only actions with the specified reference are considered
860
+ const { action$ } = this._useScopedActions(bookmarkId);
861
+ // observable stream that emits the bookmark data when the fetch action is successful
862
+ const success$ = action$.pipe(filter(bookmarkActions.fetchBookmark.success.match), map((action) => action.payload), first());
863
+ // observable stream that emits an error when fetching bookmark data fails
864
+ const failure$ = __classPrivateFieldGet(this, _BookmarkProvider_store, "f").action$.pipe(filter(bookmarkActions.fetchBookmark.failure.match), map((action) => {
865
+ throw new BookmarkProviderError(`Failed to fetch bookmark data: ${bookmarkId}`, action.payload);
866
+ }), timeout({
867
+ each: (_a = options === null || options === void 0 ? void 0 : options.timeout) !== null && _a !== void 0 ? _a : 2 * 60 * 1000,
868
+ with: () => {
869
+ throw new BookmarkProviderError(`Timeout while fetching bookmark data: ${bookmarkId}`);
870
+ },
871
+ }));
872
+ __classPrivateFieldGet(this, _BookmarkProvider_store, "f").next(bookmarkActions.fetchBookmark(bookmarkId, { ref: bookmarkId }));
873
+ return success$.pipe(raceWith(failure$));
874
+ }
875
+ _getBookmarkData(bookmarkId, options) {
876
+ var _a;
877
+ // only actions with the specified reference are considered
878
+ const { action$ } = this._useScopedActions(bookmarkId);
879
+ // observable stream that emits the bookmark data when the fetch action is successful
880
+ const success$ = action$.pipe(filter(bookmarkActions.fetchBookmarkData.success.match), map((action) => action.payload.data), first());
881
+ // observable stream that emits an error when fetching bookmark data fails
882
+ const failure$ = __classPrivateFieldGet(this, _BookmarkProvider_store, "f").action$.pipe(filter(bookmarkActions.fetchBookmarkData.failure.match), map((action) => {
883
+ throw new BookmarkProviderError(`Failed to fetch bookmark data: ${bookmarkId}`, action.payload);
884
+ }), timeout({
885
+ each: (_a = options === null || options === void 0 ? void 0 : options.timeout) !== null && _a !== void 0 ? _a : defaultTimeout,
886
+ with: () => {
887
+ throw new BookmarkProviderError(`Timeout while fetching bookmark data: ${bookmarkId}`);
888
+ },
889
+ }));
890
+ // request the store to fetch the bookmark data
891
+ __classPrivateFieldGet(this, _BookmarkProvider_store, "f").next(bookmarkActions.fetchBookmarkData(bookmarkId, { ref: bookmarkId }));
892
+ return success$.pipe(raceWith(failure$));
893
+ }
894
+ /**
895
+ * Dispatches an event of the specified type with the provided arguments.
896
+ *
897
+ * @param type - The type of the event to dispatch.
898
+ * @param args - The arguments to pass to the event.
899
+ * @returns A promise that resolves with the result of the event dispatch.
900
+ */
901
+ _dispatchEvent(type, args) {
902
+ return __awaiter(this, void 0, void 0, function* () {
903
+ var _a, _b;
904
+ // create a new event instance
905
+ const event = new FrameworkEvent(type, Object.assign({ source: this, canBubble: true }, args));
906
+ if (this._event) {
907
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug(`dispatching event ${type}`, args);
908
+ const { canceled } = yield this._event.dispatchEvent(event);
909
+ if (canceled) {
910
+ (_b = this._log) === null || _b === void 0 ? void 0 : _b.debug(`event ${type} was canceled`, args);
911
+ }
912
+ }
913
+ return event;
914
+ });
915
+ }
916
+ _useScopedActions(ref) {
917
+ /**
918
+ * Generates a unique identifier for the operation
919
+ */
920
+ ref !== null && ref !== void 0 ? ref : (ref = generateGUID());
921
+ /**
922
+ * Observable stream of actions filtered by a specific reference.
923
+ */
924
+ const action$ = __classPrivateFieldGet(this, _BookmarkProvider_store, "f").action$.pipe(filter((action) => { var _a; return 'meta' in action && ((_a = action.meta) === null || _a === void 0 ? void 0 : _a.ref) === ref; }));
925
+ return { ref, action$ };
926
+ }
927
+ /**
928
+ * Disposes the BookmarkProvider.
929
+ */
930
+ dispose() {
931
+ var _a;
932
+ (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug('disposing BookmarkProvider');
933
+ __classPrivateFieldGet(this, _BookmarkProvider_subscriptions, "f").unsubscribe();
934
+ }
935
+ }
936
+ _BookmarkProvider_config = new WeakMap(), _BookmarkProvider_store = new WeakMap(), _BookmarkProvider_payloadGenerators = new WeakMap(), _BookmarkProvider_subscriptions = new WeakMap();
937
+ //# sourceMappingURL=BookmarkProvider.js.map