@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.cjs.js +93 -43
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +25 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.js +94 -44
- package/dist/index.es.js.map +1 -1
- package/package.json +6 -6
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:
|
|
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
|
|
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:
|
|
231
|
+
* @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false }`
|
|
226
232
|
*/
|
|
227
233
|
export const useOutbox: (options?: UseCollectionOptions) => {
|
|
228
|
-
totalItems: number
|
|
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:
|
|
314
|
+
* @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false }`
|
|
306
315
|
*/
|
|
307
316
|
export const useInbox: (options?: UseCollectionOptions) => {
|
|
308
|
-
totalItems: number
|
|
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
|
|
347
|
+
export const useNodeinfo: (host?: string, rel?: string) => NodeInfo | undefined;
|
|
336
348
|
export function useWebfinger(): {
|
|
337
349
|
fetch: (id: any) => Promise<any>;
|
|
338
350
|
};
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"
|
|
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 ?
|
|
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:
|
|
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 =
|
|
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 ??
|
|
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
|
|
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
|
-
|
|
229
|
-
|
|
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
|
|
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((
|
|
284
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 = (
|
|
376
|
+
*/ const $600ca419166a1ded$var$useAwaitActivity = (awaitWebSocketConnection, existingActivities)=>{
|
|
338
377
|
const dataProvider = (0, $85cNH$useDataProvider)();
|
|
339
|
-
// TODO Allow to pass an
|
|
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
|
-
|
|
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
|
-
|
|
387
|
+
removeListeners();
|
|
349
388
|
return resolve(json);
|
|
350
389
|
}
|
|
351
390
|
});
|
|
352
391
|
};
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
392
|
+
const onError = (e)=>{
|
|
393
|
+
// TODO reconnect if connection closed
|
|
394
|
+
removeListeners();
|
|
356
395
|
reject(e);
|
|
357
|
-
}
|
|
358
|
-
|
|
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
|
-
|
|
413
|
+
removeListeners();
|
|
366
414
|
return resolve(a);
|
|
367
415
|
}
|
|
368
416
|
}
|
|
369
417
|
}
|
|
370
418
|
setTimeout(()=>{
|
|
371
|
-
|
|
419
|
+
removeListeners();
|
|
372
420
|
reject(new Error("Timeout"));
|
|
373
421
|
}, timeout);
|
|
374
|
-
}
|
|
422
|
+
}).catch((e)=>{
|
|
423
|
+
reject(e);
|
|
424
|
+
});
|
|
375
425
|
});
|
|
376
426
|
}, [
|
|
377
|
-
|
|
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:
|
|
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,
|
|
397
|
-
const awaitActivity = (0, $600ca419166a1ded$export$2e2bcd8739ae039)(
|
|
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:
|
|
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 {
|
|
879
|
-
const awaitActivity = (0, $600ca419166a1ded$export$2e2bcd8739ae039)(
|
|
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
|
-
|
|
932
|
+
items: items,
|
|
933
|
+
awaitWebSocketConnection: awaitWebSocketConnection,
|
|
884
934
|
awaitActivity: awaitActivity,
|
|
885
935
|
owner: identity?.id,
|
|
886
936
|
...rest
|