@semapps/activitypub-components 0.7.0 → 0.8.1

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/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { RefObject } from 'react';
1
2
  export declare namespace ACTIVITY_TYPES {
2
3
  let ACCEPT: string;
3
4
  let ADD: string;
@@ -54,6 +55,10 @@ interface UseCollectionOptions {
54
55
  dereferenceItems?: boolean;
55
56
  liveUpdates?: boolean;
56
57
  }
58
+ interface AwaitActivityOptions {
59
+ timeout?: number;
60
+ checkExistingActivities?: boolean;
61
+ }
57
62
  /**
58
63
  * NodeInfo schema version 2.1.
59
64
  */
@@ -187,14 +192,14 @@ interface NodeInfo {
187
192
  /**
188
193
  * Subscribe a collection. Supports pagination.
189
194
  * @param predicateOrUrl The collection URI or the predicate to get the collection URI from the identity (webId).
190
- * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: true }`
195
+ * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false }`
191
196
  */
192
197
  export const useCollection: (
193
198
  predicateOrUrl: string,
194
199
  options?: UseCollectionOptions
195
200
  ) => {
196
201
  items: any[];
197
- totalItems: number | undefined;
202
+ totalItems: number;
198
203
  error: false | unknown[];
199
204
  refetch: <TPageData>(
200
205
  options?: (import('react-query').RefetchOptions & import('react-query').RefetchQueryFilters<TPageData>) | undefined
@@ -212,8 +217,9 @@ export const useCollection: (
212
217
  hasLiveUpdates: {
213
218
  status: string;
214
219
  error?: any;
215
- webSocket?: WebSocket | undefined;
216
220
  };
221
+ awaitWebSocketConnection: (options?: AwaitActivityOptions) => Promise<RefObject<WebSocket>>;
222
+ webSocketRef: import('react').MutableRefObject<WebSocket | null>;
217
223
  };
218
224
  /**
219
225
  * Hook to fetch and post to the outbox of the logged user.
@@ -222,10 +228,10 @@ export const useCollection: (
222
228
  * - `awaitActivity`: a function to wait for a certain activity to be posted
223
229
  * - `owner`: the WebID of the outbox's owner
224
230
  * See https://semapps.org/docs/frontend/activitypub-components#useoutbox for usage
225
- * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: true }`
231
+ * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false }`
226
232
  */
227
233
  export const useOutbox: (options?: UseCollectionOptions) => {
228
- totalItems: number | undefined;
234
+ totalItems: number;
229
235
  error: false | unknown[];
230
236
  refetch: <TPageData>(
231
237
  options?: (import('react-query').RefetchOptions & import('react-query').RefetchQueryFilters<TPageData>) | undefined
@@ -239,13 +245,16 @@ export const useOutbox: (options?: UseCollectionOptions) => {
239
245
  isLoading: boolean;
240
246
  isFetching: boolean;
241
247
  isFetchingNextPage: boolean;
242
- url: any;
243
248
  hasLiveUpdates: {
244
249
  status: string;
245
250
  error?: any;
246
- webSocket?: WebSocket | undefined;
247
251
  };
252
+ webSocketRef: import('react').MutableRefObject<WebSocket | null>;
253
+ url: any;
248
254
  items: any[];
255
+ awaitWebSocketConnection: (
256
+ options?: import('types').AwaitActivityOptions
257
+ ) => Promise<import('react').RefObject<WebSocket>>;
249
258
  post: (activity: object) => Promise<string | null>;
250
259
  awaitActivity: (
251
260
  matchActivity: (activity: object) => boolean,
@@ -302,10 +311,10 @@ export function ReferenceCollectionField({
302
311
  * - `awaitActivity`: a function to wait for a certain activity to be received
303
312
  * - `owner`: the WebID of the inbox's owner
304
313
  * See https://semapps.org/docs/frontend/activitypub-components#useinbox for usage
305
- * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: true }`
314
+ * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false }`
306
315
  */
307
316
  export const useInbox: (options?: UseCollectionOptions) => {
308
- totalItems: number | undefined;
317
+ totalItems: number;
309
318
  error: false | unknown[];
310
319
  refetch: <TPageData>(
311
320
  options?: (import('react-query').RefetchOptions & import('react-query').RefetchQueryFilters<TPageData>) | undefined
@@ -319,20 +328,23 @@ export const useInbox: (options?: UseCollectionOptions) => {
319
328
  isLoading: boolean;
320
329
  isFetching: boolean;
321
330
  isFetchingNextPage: boolean;
322
- items: any[];
323
- url: any;
324
331
  hasLiveUpdates: {
325
332
  status: string;
326
333
  error?: any;
327
- webSocket?: WebSocket | undefined;
328
334
  };
335
+ webSocketRef: import('react').MutableRefObject<WebSocket | null>;
336
+ url: any;
337
+ items: any[];
338
+ awaitWebSocketConnection: (
339
+ options?: import('types').AwaitActivityOptions
340
+ ) => Promise<import('react').RefObject<WebSocket>>;
329
341
  awaitActivity: (
330
342
  matchActivity: (activity: object) => boolean,
331
343
  options?: import('types').AwaitActivityOptions
332
344
  ) => Promise<unknown>;
333
345
  owner: import('react-admin').Identifier | undefined;
334
346
  };
335
- export const useNodeinfo: (host: string, rel?: string) => NodeInfo | undefined;
347
+ export const useNodeinfo: (host?: string, rel?: string) => NodeInfo | undefined;
336
348
  export function useWebfinger(): {
337
349
  fetch: (id: any) => Promise<any>;
338
350
  };
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/activitypub-components/src/src/constants.js","packages/activitypub-components/src/src/utils.ts","packages/activitypub-components/src/src/types.ts","packages/activitypub-components/src/src/hooks/useCollection.ts","packages/activitypub-components/src/src/hooks/useAwaitActivity.ts","packages/activitypub-components/src/src/hooks/useOutbox.ts","packages/activitypub-components/src/src/components/CommentsField/CustomMention.js","packages/activitypub-components/src/src/components/CommentsField/PostCommentForm.js","packages/activitypub-components/src/src/components/CommentsField/CommentsList.js","packages/activitypub-components/src/src/components/CommentsField/CommentsField.js","packages/activitypub-components/src/src/components/CollectionList.js","packages/activitypub-components/src/src/components/ReferenceCollectionField.js","packages/activitypub-components/src/src/hooks/useInbox.ts","packages/activitypub-components/src/src/hooks/useNodeinfo.ts","packages/activitypub-components/src/src/hooks/useWebfinger.js","packages/activitypub-components/src/src/hooks/useMentions/MentionsList.js","packages/activitypub-components/src/src/hooks/useMentions/renderMentions.js","packages/activitypub-components/src/src/hooks/useMentions/useMentions.js","packages/activitypub-components/src/src/index.ts","packages/activitypub-components/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"// Components\nexport { default as CommentsField } from './components/CommentsField/CommentsField';\nexport { default as CollectionList } from './components/CollectionList';\nexport { default as ReferenceCollectionField } from './components/ReferenceCollectionField';\n\n// Hooks\nexport { default as useCollection } from './hooks/useCollection';\nexport { default as useInbox } from './hooks/useInbox';\nexport { default as useNodeinfo } from './hooks/useNodeinfo';\nexport { default as useOutbox } from './hooks/useOutbox';\nexport { default as useWebfinger } from './hooks/useWebfinger';\nexport { default as useMentions } from './hooks/useMentions/useMentions';\n\n// Constants\nexport { ACTIVITY_TYPES, ACTOR_TYPES, OBJECT_TYPES, PUBLIC_URI } from './constants';\n"],"names":[],"version":3,"file":"index.d.ts.map"}
1
+ {"mappings":"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","sources":["packages/activitypub-components/src/src/constants.js","packages/activitypub-components/src/src/utils.ts","packages/activitypub-components/src/src/types.ts","packages/activitypub-components/src/src/hooks/useCollection.ts","packages/activitypub-components/src/src/hooks/useAwaitActivity.ts","packages/activitypub-components/src/src/hooks/useOutbox.ts","packages/activitypub-components/src/src/components/CommentsField/CustomMention.js","packages/activitypub-components/src/src/components/CommentsField/PostCommentForm.js","packages/activitypub-components/src/src/components/CommentsField/CommentsList.js","packages/activitypub-components/src/src/components/CommentsField/CommentsField.js","packages/activitypub-components/src/src/components/CollectionList.js","packages/activitypub-components/src/src/components/ReferenceCollectionField.js","packages/activitypub-components/src/src/hooks/useInbox.ts","packages/activitypub-components/src/src/hooks/useNodeinfo.ts","packages/activitypub-components/src/src/hooks/useWebfinger.js","packages/activitypub-components/src/src/hooks/useMentions/MentionsList.js","packages/activitypub-components/src/src/hooks/useMentions/renderMentions.js","packages/activitypub-components/src/src/hooks/useMentions/useMentions.js","packages/activitypub-components/src/src/index.ts","packages/activitypub-components/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"// Components\nexport { default as CommentsField } from './components/CommentsField/CommentsField';\nexport { default as CollectionList } from './components/CollectionList';\nexport { default as ReferenceCollectionField } from './components/ReferenceCollectionField';\n\n// Hooks\nexport { default as useCollection } from './hooks/useCollection';\nexport { default as useInbox } from './hooks/useInbox';\nexport { default as useNodeinfo } from './hooks/useNodeinfo';\nexport { default as useOutbox } from './hooks/useOutbox';\nexport { default as useWebfinger } from './hooks/useWebfinger';\nexport { default as useMentions } from './hooks/useMentions/useMentions';\n\n// Constants\nexport { ACTIVITY_TYPES, ACTOR_TYPES, OBJECT_TYPES, PUBLIC_URI } from './constants';\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/dist/index.es.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import {jsxs as $85cNH$jsxs, Fragment as $85cNH$Fragment, jsx as $85cNH$jsx} from "react/jsx-runtime";
2
- import $85cNH$react, {useState as $85cNH$useState, useCallback as $85cNH$useCallback, useMemo as $85cNH$useMemo, useEffect as $85cNH$useEffect, forwardRef as $85cNH$forwardRef, useImperativeHandle as $85cNH$useImperativeHandle} from "react";
2
+ import $85cNH$react, {useState as $85cNH$useState, useCallback as $85cNH$useCallback, useMemo as $85cNH$useMemo, useRef as $85cNH$useRef, useEffect as $85cNH$useEffect, forwardRef as $85cNH$forwardRef, useImperativeHandle as $85cNH$useImperativeHandle} from "react";
3
3
  import {useRecordContext as $85cNH$useRecordContext, useGetIdentity as $85cNH$useGetIdentity, useNotify as $85cNH$useNotify, Form as $85cNH$Form, useDataProvider as $85cNH$useDataProvider, TextField as $85cNH$TextField, DateField as $85cNH$DateField, RichTextField as $85cNH$RichTextField, useGetMany as $85cNH$useGetMany, useList as $85cNH$useList, ListContextProvider as $85cNH$ListContextProvider, fetchUtils as $85cNH$fetchUtils, useGetList as $85cNH$useGetList} from "react-admin";
4
4
  import {RichTextInput as $85cNH$RichTextInput, DefaultEditorOptions as $85cNH$DefaultEditorOptions} from "ra-input-rich-text";
5
5
  import $85cNH$tiptapextensionplaceholder from "@tiptap/extension-placeholder";
@@ -113,6 +113,8 @@ const $577f4953dfa5de4f$export$34aed805e991a647 = (iterable, predicate)=>{
113
113
  };
114
114
 
115
115
 
116
+ // Used to avoid re-renders
117
+ const $8281f3ce3b9d6123$var$emptyArray = [];
116
118
  const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
117
119
  const dataProvider = (0, $85cNH$useDataProvider)();
118
120
  const items = (0, $85cNH$useMemo)(()=>pages.flatMap((p)=>(0, $577f4953dfa5de4f$export$e57ff0f701c44363)(p.orderedItems || p.items)), [
@@ -126,7 +128,7 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
126
128
  items
127
129
  ]);
128
130
  // Dereference all items, if necessary (even if shouldDereference is false, the hook needs to be called).
129
- const itemQueries = (0, $85cNH$useQueries)(!shouldDereference ? [] : items.filter((item)=>typeof item === "string").map((itemUri)=>({
131
+ const itemQueries = (0, $85cNH$useQueries)(!shouldDereference ? $8281f3ce3b9d6123$var$emptyArray : items.filter((item)=>typeof item === "string").map((itemUri)=>({
130
132
  queryKey: [
131
133
  "resource",
132
134
  itemUri
@@ -154,16 +156,17 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
154
156
  /**
155
157
  * Subscribe a collection. Supports pagination.
156
158
  * @param predicateOrUrl The collection URI or the predicate to get the collection URI from the identity (webId).
157
- * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: true }`
159
+ * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false }`
158
160
  */ const $8281f3ce3b9d6123$var$useCollection = (predicateOrUrl, options = {})=>{
159
- const { dereferenceItems: dereferenceItems = false, liveUpdates: liveUpdates = true } = options;
161
+ const { dereferenceItems: dereferenceItems = false, liveUpdates: liveUpdates = false } = options;
160
162
  const { data: identity } = (0, $85cNH$useGetIdentity)();
161
- const [totalItems, setTotalItems] = (0, $85cNH$useState)();
163
+ const [totalItems, setTotalItems] = (0, $85cNH$useState)(0);
162
164
  const queryClient = (0, $85cNH$useQueryClient)();
163
165
  const [hasLiveUpdates, setHasLiveUpdates] = (0, $85cNH$useState)({
164
166
  status: "connecting"
165
167
  });
166
168
  const dataProvider = (0, $85cNH$useDataProvider)();
169
+ const webSocketRef = (0, $85cNH$useRef)(null);
167
170
  // Get collectionUrl from webId predicate or URL.
168
171
  const collectionUrl = (0, $85cNH$useMemo)(()=>{
169
172
  if (predicateOrUrl) {
@@ -210,7 +213,7 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
210
213
  getPreviousPageParam: (firstPage)=>firstPage.prev
211
214
  });
212
215
  // Put all items together in a list (and dereference, if required).
213
- const { loadedItems: items, isLoading: isLoadingItems, isFetching: isFetchingItems, errors: itemErrors } = $8281f3ce3b9d6123$var$useItemsFromPages(pageData?.pages ?? [], dereferenceItems);
216
+ const { loadedItems: items, isLoading: isLoadingItems, isFetching: isFetchingItems, errors: itemErrors } = $8281f3ce3b9d6123$var$useItemsFromPages(pageData?.pages ?? $8281f3ce3b9d6123$var$emptyArray, dereferenceItems);
214
217
  const allErrors = (0, $577f4953dfa5de4f$export$e57ff0f701c44363)(collectionError).concat((0, $577f4953dfa5de4f$export$e57ff0f701c44363)(itemErrors));
215
218
  const addItem = (0, $85cNH$useCallback)((item, shouldRefetch = true)=>{
216
219
  queryClient.setQueryData([
@@ -220,13 +223,19 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
220
223
  }
221
224
  ], (oldData)=>{
222
225
  if (!oldData) return oldData;
223
- setTotalItems(totalItems && totalItems + 1);
226
+ setTotalItems((totalItems)=>totalItems + 1);
224
227
  // Destructure, so react knows, it needs to re-render the pages.
225
228
  const pages = [
226
229
  ...oldData.pages
227
230
  ];
228
- const firstPageItems = pages?.[0]?.orderedItems || pages?.[0]?.items || [];
229
- firstPageItems.unshift(item);
231
+ if (pages?.[0]?.orderedItems) pages[0].orderedItems = [
232
+ item,
233
+ ...(0, $577f4953dfa5de4f$export$e57ff0f701c44363)(pages[0].orderedItems)
234
+ ];
235
+ else if (pages?.[0]?.items) pages[0].items = [
236
+ item,
237
+ ...(0, $577f4953dfa5de4f$export$e57ff0f701c44363)(pages[0].items)
238
+ ];
230
239
  oldData.pages = pages;
231
240
  return oldData;
232
241
  });
@@ -241,7 +250,8 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
241
250
  }), typeof shouldRefetch === "number" ? shouldRefetch : 2000);
242
251
  }, [
243
252
  queryClient,
244
- collectionUrl
253
+ collectionUrl,
254
+ setTotalItems
245
255
  ]);
246
256
  const removeItem = (0, $85cNH$useCallback)((item, shouldRefetch = true)=>{
247
257
  queryClient.setQueryData([
@@ -251,7 +261,7 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
251
261
  }
252
262
  ], (oldData)=>{
253
263
  if (!oldData) return oldData;
254
- setTotalItems(totalItems && totalItems - 1);
264
+ setTotalItems((totalItems)=>totalItems - 1);
255
265
  // Destructure, so react knows, it needs to re-render the pages array.
256
266
  const pages = [
257
267
  ...oldData.pages
@@ -275,39 +285,66 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
275
285
  }), typeof shouldRefetch === "number" ? shouldRefetch : 2000);
276
286
  }, [
277
287
  queryClient,
278
- collectionUrl
288
+ collectionUrl,
289
+ setTotalItems
279
290
  ]);
280
291
  // Live Updates
281
292
  (0, $85cNH$useEffect)(()=>{
282
293
  if (liveUpdates && collectionUrl) // Create ws that listens to collectionUri changes
283
- (0, $85cNH$getOrCreateWsChannel)(dataProvider.fetch, collectionUrl).then((webSocket)=>{
284
- webSocket.addEventListener("message", (e)=>{
294
+ (0, $85cNH$getOrCreateWsChannel)(dataProvider.fetch, collectionUrl).then((ws)=>{
295
+ webSocketRef.current = ws; // Keep a ref to the webSocket so that it can be used elsewhere
296
+ webSocketRef.current.addEventListener("message", (e)=>{
285
297
  const data = JSON.parse(e.data);
286
298
  if (data.type === "Add") addItem(data.object, true);
287
299
  else if (data.type === "Remove") removeItem(data.object, true);
288
300
  });
289
- webSocket.addEventListener("error", (e)=>{
301
+ webSocketRef.current.addEventListener("error", (e)=>{
290
302
  setHasLiveUpdates({
291
303
  status: "error",
292
304
  error: e
293
305
  });
294
306
  // TODO: Retry after a while
295
307
  });
296
- webSocket.addEventListener("close", (e)=>{
308
+ webSocketRef.current.addEventListener("close", (e)=>{
297
309
  if (!hasLiveUpdates.error) setHasLiveUpdates({
298
310
  ...hasLiveUpdates,
299
311
  status: "closed"
300
312
  });
301
313
  });
302
314
  setHasLiveUpdates({
303
- status: "connected",
304
- webSocket: webSocket
315
+ status: "connected"
305
316
  });
306
317
  }).catch(()=>{}); // If it fails, we won't receive live updates. But that's okay.
307
318
  }, [
308
319
  collectionUrl,
309
320
  liveUpdates,
310
- dataProvider
321
+ dataProvider,
322
+ webSocketRef,
323
+ addItem,
324
+ removeItem,
325
+ setHasLiveUpdates
326
+ ]);
327
+ const awaitWebSocketConnection = (0, $85cNH$useCallback)((options = {})=>{
328
+ const { timeout: timeout = 30000 } = options;
329
+ if (!liveUpdates) throw new Error(`Cannot call awaitWebSocketConnection because the liveUpdates option is set to false`);
330
+ return new Promise((resolve, reject)=>{
331
+ if (webSocketRef?.current) resolve(webSocketRef);
332
+ else {
333
+ const timeoutId = setTimeout(()=>{
334
+ reject(`No WebSocket connection found within ${Math.round(timeout / 1000)}s`);
335
+ }, timeout);
336
+ const intervalId = setInterval(()=>{
337
+ if (webSocketRef?.current) {
338
+ clearInterval(intervalId);
339
+ clearTimeout(timeoutId);
340
+ resolve(webSocketRef);
341
+ } else console.log("WebSocket is not initialized yet, waiting...");
342
+ }, 100);
343
+ }
344
+ });
345
+ }, [
346
+ webSocketRef,
347
+ liveUpdates
311
348
  ]);
312
349
  return {
313
350
  items: items,
@@ -322,7 +359,9 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
322
359
  isFetching: isFetchingPage || isFetchingItems,
323
360
  isFetchingNextPage: isFetchingNextPage,
324
361
  url: collectionUrl,
325
- hasLiveUpdates: hasLiveUpdates
362
+ hasLiveUpdates: hasLiveUpdates,
363
+ awaitWebSocketConnection: awaitWebSocketConnection,
364
+ webSocketRef: webSocketRef
326
365
  };
327
366
  };
328
367
  var $8281f3ce3b9d6123$export$2e2bcd8739ae039 = $8281f3ce3b9d6123$var$useCollection;
@@ -332,49 +371,60 @@ var $8281f3ce3b9d6123$export$2e2bcd8739ae039 = $8281f3ce3b9d6123$var$useCollecti
332
371
 
333
372
  /**
334
373
  * Hook used internally by useInbox and useOutbox. This is not exported.
335
- * @param webSocket WebSocket which allow to listen to the inbox or outbox
374
+ * @param awaitWebSocketConnection Promise returning the WebSocket which allow to listen to the inbox or outbox
336
375
  * @param existingActivities Partial list of activities already received in the inbox and outbox
337
- */ const $600ca419166a1ded$var$useAwaitActivity = (webSocket, existingActivities)=>{
376
+ */ const $600ca419166a1ded$var$useAwaitActivity = (awaitWebSocketConnection, existingActivities)=>{
338
377
  const dataProvider = (0, $85cNH$useDataProvider)();
339
- // TODO Allow to pass an object, and automatically dereference it if required, like on the @semapps/activitypub matchActivity util
378
+ // TODO Allow to pass an object, and automatically dereference it if required, like on the @semapps/activitypub matchActivity util
340
379
  return (0, $85cNH$useCallback)((matchActivity, options = {})=>{
341
380
  const { timeout: timeout = 30000, checkExistingActivities: checkExistingActivities = false } = options;
342
381
  return new Promise((resolve, reject)=>{
343
- if (webSocket) {
382
+ awaitWebSocketConnection().then((webSocketRef)=>{
344
383
  const onMessage = (event)=>{
345
384
  const data = JSON.parse(event.data);
346
385
  if (data.type === "Add") dataProvider.fetch(data.object).then(({ json: json })=>{
347
386
  if (matchActivity(json)) {
348
- webSocket.removeEventListener("message", onMessage);
387
+ removeListeners();
349
388
  return resolve(json);
350
389
  }
351
390
  });
352
391
  };
353
- webSocket.addEventListener("message", onMessage);
354
- // TODO reconnect if connection closed
355
- webSocket.addEventListener("error", (e)=>{
392
+ const onError = (e)=>{
393
+ // TODO reconnect if connection closed
394
+ removeListeners();
356
395
  reject(e);
357
- });
358
- webSocket.addEventListener("close", (e)=>{
396
+ };
397
+ const onClose = (e)=>{
398
+ removeListeners();
359
399
  reject(new Error(`${e.reason} (Code: ${e.code})`));
360
- });
400
+ };
401
+ const removeListeners = ()=>{
402
+ webSocketRef.current?.removeEventListener("message", onMessage);
403
+ webSocketRef.current?.removeEventListener("error", onError);
404
+ webSocketRef.current?.removeEventListener("close", onClose);
405
+ };
406
+ webSocketRef.current?.addEventListener("message", onMessage);
407
+ webSocketRef.current?.addEventListener("error", onError);
408
+ webSocketRef.current?.addEventListener("close", onClose);
361
409
  // If a list of activities is already loaded, verify if there is a match
362
410
  if (existingActivities && checkExistingActivities) for (const a of existingActivities){
363
411
  if (typeof a !== "string") {
364
412
  if (matchActivity(a)) {
365
- webSocket.removeEventListener("message", onMessage);
413
+ removeListeners();
366
414
  return resolve(a);
367
415
  }
368
416
  }
369
417
  }
370
418
  setTimeout(()=>{
371
- webSocket.removeEventListener("message", onMessage);
419
+ removeListeners();
372
420
  reject(new Error("Timeout"));
373
421
  }, timeout);
374
- } else throw new Error("WebSocket is not initialized !");
422
+ }).catch((e)=>{
423
+ reject(e);
424
+ });
375
425
  });
376
426
  }, [
377
- webSocket,
427
+ awaitWebSocketConnection,
378
428
  existingActivities,
379
429
  dataProvider
380
430
  ]);
@@ -389,12 +439,12 @@ var $600ca419166a1ded$export$2e2bcd8739ae039 = $600ca419166a1ded$var$useAwaitAct
389
439
  * - `awaitActivity`: a function to wait for a certain activity to be posted
390
440
  * - `owner`: the WebID of the outbox's owner
391
441
  * See https://semapps.org/docs/frontend/activitypub-components#useoutbox for usage
392
- * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: true }`
442
+ * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false }`
393
443
  */ const $4d1d40fdbcd30589$var$useOutbox = (options = {})=>{
394
444
  const dataProvider = (0, $85cNH$useDataProvider)();
395
445
  const { data: identity } = (0, $85cNH$useGetIdentity)();
396
- const { url: url, hasLiveUpdates: hasLiveUpdates, items: items, ...rest } = (0, $8281f3ce3b9d6123$export$2e2bcd8739ae039)("outbox", options);
397
- const awaitActivity = (0, $600ca419166a1ded$export$2e2bcd8739ae039)(hasLiveUpdates.webSocket, items);
446
+ const { url: url, items: items, awaitWebSocketConnection: awaitWebSocketConnection, ...rest } = (0, $8281f3ce3b9d6123$export$2e2bcd8739ae039)("outbox", options);
447
+ const awaitActivity = (0, $600ca419166a1ded$export$2e2bcd8739ae039)(awaitWebSocketConnection, items);
398
448
  // Post an activity to the logged user's outbox and return its URI
399
449
  const post = (0, $85cNH$useCallback)(async (activity)=>{
400
450
  if (!url) throw new Error("Cannot post to outbox before user identity is loaded. Please use the isLoading argument of useOutbox");
@@ -412,8 +462,8 @@ var $600ca419166a1ded$export$2e2bcd8739ae039 = $600ca419166a1ded$var$useAwaitAct
412
462
  ]);
413
463
  return {
414
464
  url: url,
415
- hasLiveUpdates: hasLiveUpdates,
416
465
  items: items,
466
+ awaitWebSocketConnection: awaitWebSocketConnection,
417
467
  post: post,
418
468
  awaitActivity: awaitActivity,
419
469
  owner: identity?.id,
@@ -872,15 +922,15 @@ var $ea214512ab1a2e8f$export$2e2bcd8739ae039 = $ea214512ab1a2e8f$var$ReferenceCo
872
922
  * - `awaitActivity`: a function to wait for a certain activity to be received
873
923
  * - `owner`: the WebID of the inbox's owner
874
924
  * See https://semapps.org/docs/frontend/activitypub-components#useinbox for usage
875
- * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: true }`
925
+ * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false }`
876
926
  */ const $cc1d1cd0e97c63a2$var$useInbox = (options = {})=>{
877
927
  const { data: identity } = (0, $85cNH$useGetIdentity)();
878
- const { items: items, url: url, hasLiveUpdates: hasLiveUpdates, ...rest } = (0, $8281f3ce3b9d6123$export$2e2bcd8739ae039)("inbox", options);
879
- const awaitActivity = (0, $600ca419166a1ded$export$2e2bcd8739ae039)(hasLiveUpdates.webSocket);
928
+ const { url: url, items: items, awaitWebSocketConnection: awaitWebSocketConnection, ...rest } = (0, $8281f3ce3b9d6123$export$2e2bcd8739ae039)("inbox", options);
929
+ const awaitActivity = (0, $600ca419166a1ded$export$2e2bcd8739ae039)(awaitWebSocketConnection, items);
880
930
  return {
881
- items: items,
882
931
  url: url,
883
- hasLiveUpdates: hasLiveUpdates,
932
+ items: items,
933
+ awaitWebSocketConnection: awaitWebSocketConnection,
884
934
  awaitActivity: awaitActivity,
885
935
  owner: identity?.id,
886
936
  ...rest