@semapps/activitypub-components 0.6.7 → 0.7.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.
package/dist/index.es.js CHANGED
@@ -1,17 +1,17 @@
1
1
  import {jsxs as $85cNH$jsxs, Fragment as $85cNH$Fragment, jsx as $85cNH$jsx} from "react/jsx-runtime";
2
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";
3
- import {useRecordContext as $85cNH$useRecordContext, useGetIdentity as $85cNH$useGetIdentity, useNotify as $85cNH$useNotify, Form as $85cNH$Form, fetchUtils as $85cNH$fetchUtils, TextField as $85cNH$TextField, DateField as $85cNH$DateField, RichTextField as $85cNH$RichTextField, useDataProvider as $85cNH$useDataProvider, useGetMany as $85cNH$useGetMany, useList as $85cNH$useList, ListContextProvider as $85cNH$ListContextProvider, useGetList as $85cNH$useGetList} from "react-admin";
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";
6
6
  import {Box as $85cNH$Box, Avatar as $85cNH$Avatar, Button as $85cNH$Button, Typography as $85cNH$Typography, CircularProgress as $85cNH$CircularProgress} from "@mui/material";
7
7
  import $85cNH$muistylesmakeStyles from "@mui/styles/makeStyles";
8
8
  import $85cNH$muiiconsmaterialSend from "@mui/icons-material/Send";
9
- import {useDataModel as $85cNH$useDataModel, buildBlankNodesQuery as $85cNH$buildBlankNodesQuery, getOrCreateWsChannel as $85cNH$getOrCreateWsChannel} from "@semapps/semantic-data-provider";
9
+ import {useDataModel as $85cNH$useDataModel, getOrCreateWsChannel as $85cNH$getOrCreateWsChannel} from "@semapps/semantic-data-provider";
10
10
  import {AuthDialog as $85cNH$AuthDialog} from "@semapps/auth-provider";
11
+ import {useQueries as $85cNH$useQueries, useQueryClient as $85cNH$useQueryClient, useInfiniteQuery as $85cNH$useInfiniteQuery} from "react-query";
11
12
  import {mergeAttributes as $85cNH$mergeAttributes} from "@tiptap/core";
12
13
  import $85cNH$tiptapextensionmention from "@tiptap/extension-mention";
13
14
  import {ReferenceField as $85cNH$ReferenceField, AvatarWithLabelField as $85cNH$AvatarWithLabelField} from "@semapps/field-components";
14
- import {useQueries as $85cNH$useQueries, useInfiniteQuery as $85cNH$useInfiniteQuery, useQueryClient as $85cNH$useQueryClient} from "react-query";
15
15
  import {ReactRenderer as $85cNH$ReactRenderer} from "@tiptap/react";
16
16
  import $85cNH$tippyjs from "tippy.js";
17
17
 
@@ -86,78 +86,341 @@ const $338f387df48a40d7$export$4d8d554031975581 = "https://www.w3.org/ns/activit
86
86
 
87
87
 
88
88
 
89
- const $712f7f004b5f345e$var$useOutbox = ()=>{
89
+
90
+
91
+
92
+ const $577f4953dfa5de4f$export$e57ff0f701c44363 = (value)=>{
93
+ // If the field is null-ish, we suppose there are no values.
94
+ if (value === null || value === undefined) return [];
95
+ // Return as is.
96
+ if (Array.isArray(value)) return value;
97
+ // Single value is made an array.
98
+ return [
99
+ value
100
+ ];
101
+ };
102
+ var $577f4953dfa5de4f$export$2e2bcd8739ae039 = {
103
+ arrayOf: $577f4953dfa5de4f$export$e57ff0f701c44363
104
+ };
105
+ const $577f4953dfa5de4f$export$34aed805e991a647 = (iterable, predicate)=>{
106
+ const seen = new Set();
107
+ return iterable.filter((item)=>{
108
+ const key = predicate(item);
109
+ if (seen.has(key)) return false;
110
+ seen.add(key);
111
+ return true;
112
+ });
113
+ };
114
+
115
+
116
+ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
117
+ const dataProvider = (0, $85cNH$useDataProvider)();
118
+ const items = (0, $85cNH$useMemo)(()=>pages.flatMap((p)=>(0, $577f4953dfa5de4f$export$e57ff0f701c44363)(p.orderedItems || p.items)), [
119
+ pages
120
+ ]);
121
+ // We will force dereference, if some items are not URI string references.
122
+ const shouldDereference = (0, $85cNH$useMemo)(()=>{
123
+ return dereferenceItems || items.some((item)=>typeof item !== "string");
124
+ }, [
125
+ dereferenceItems,
126
+ items
127
+ ]);
128
+ // 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)=>({
130
+ queryKey: [
131
+ "resource",
132
+ itemUri
133
+ ],
134
+ queryFn: async ()=>(await dataProvider.fetch(itemUri)).json,
135
+ staleTime: Infinity
136
+ })));
137
+ if (!shouldDereference) return {
138
+ loadedItems: items,
139
+ isLoading: false,
140
+ isFetching: false
141
+ };
142
+ // Put all loaded items together (might be dereferenced already, so concatenate).
143
+ const loadedItems = items.filter((item)=>typeof item !== "string").concat(itemQueries.flatMap((itemQuery)=>{
144
+ return itemQuery.isSuccess && itemQuery.data || [];
145
+ }));
146
+ const errors = itemQueries.filter((q)=>q.error);
147
+ return {
148
+ loadedItems: loadedItems,
149
+ isLoading: itemQueries.some((q)=>q.isLoading),
150
+ isFetching: itemQueries.some((q)=>q.isFetching),
151
+ errors: errors.length > 0 ? errors : undefined
152
+ };
153
+ };
154
+ /**
155
+ * Subscribe a collection. Supports pagination.
156
+ * @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 }`
158
+ */ const $8281f3ce3b9d6123$var$useCollection = (predicateOrUrl, options = {})=>{
159
+ const { dereferenceItems: dereferenceItems = false, liveUpdates: liveUpdates = true } = options;
90
160
  const { data: identity } = (0, $85cNH$useGetIdentity)();
91
- const outboxUrl = (0, $85cNH$useMemo)(()=>{
92
- if (identity?.webIdData) return identity?.webIdData?.outbox;
161
+ const [totalItems, setTotalItems] = (0, $85cNH$useState)();
162
+ const queryClient = (0, $85cNH$useQueryClient)();
163
+ const [hasLiveUpdates, setHasLiveUpdates] = (0, $85cNH$useState)({
164
+ status: "connecting"
165
+ });
166
+ const dataProvider = (0, $85cNH$useDataProvider)();
167
+ // Get collectionUrl from webId predicate or URL.
168
+ const collectionUrl = (0, $85cNH$useMemo)(()=>{
169
+ if (predicateOrUrl) {
170
+ if (predicateOrUrl.startsWith("http")) return predicateOrUrl;
171
+ if (identity?.webIdData) return identity?.webIdData?.[predicateOrUrl];
172
+ }
173
+ return undefined;
174
+ // throw new Error(`No URL available for useCollection: ${predicateOrUrl}.`);
93
175
  }, [
94
- identity
176
+ identity,
177
+ predicateOrUrl
178
+ ]);
179
+ // Fetch page of collection item references (if pageParam provided)
180
+ // or default to `collectionUrl` (which should give you the first page).
181
+ const fetchCollection = (0, $85cNH$useCallback)(async ({ pageParam: nextPageUrl })=>{
182
+ // Fetch page or first page (collectionUrl)
183
+ let { json: json } = await dataProvider.fetch(nextPageUrl || collectionUrl);
184
+ if (json.totalItems) setTotalItems(json.totalItems);
185
+ // If first page, handle this here.
186
+ if ((json.type === "OrderedCollection" || json.type === "Collection") && json.first) {
187
+ if (json.first?.items) {
188
+ if (json.first?.items.length === 0 && json.first?.next) // Special case where the first property is an object without items
189
+ ({ json: json } = await dataProvider.fetch(json.first?.next));
190
+ else json = json.first;
191
+ } else // Fetch the first page
192
+ ({ json: json } = await dataProvider.fetch(json.first));
193
+ }
194
+ return json;
195
+ }, [
196
+ dataProvider,
197
+ collectionUrl,
198
+ identity,
199
+ setTotalItems
200
+ ]);
201
+ // Use infiniteQuery to handle pagination, fetching, etc.
202
+ const { data: pageData, error: collectionError, fetchNextPage: fetchNextPage, refetch: refetch, hasNextPage: hasNextPage, isLoading: isLoadingPage, isFetching: isFetchingPage, isFetchingNextPage: isFetchingNextPage } = (0, $85cNH$useInfiniteQuery)([
203
+ "collection",
204
+ {
205
+ collectionUrl: collectionUrl
206
+ }
207
+ ], fetchCollection, {
208
+ enabled: !!(collectionUrl && identity?.id),
209
+ getNextPageParam: (lastPage)=>lastPage.next,
210
+ getPreviousPageParam: (firstPage)=>firstPage.prev
211
+ });
212
+ // 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);
214
+ const allErrors = (0, $577f4953dfa5de4f$export$e57ff0f701c44363)(collectionError).concat((0, $577f4953dfa5de4f$export$e57ff0f701c44363)(itemErrors));
215
+ const addItem = (0, $85cNH$useCallback)((item, shouldRefetch = true)=>{
216
+ queryClient.setQueryData([
217
+ "collection",
218
+ {
219
+ collectionUrl: collectionUrl
220
+ }
221
+ ], (oldData)=>{
222
+ if (!oldData) return oldData;
223
+ setTotalItems(totalItems && totalItems + 1);
224
+ // Destructure, so react knows, it needs to re-render the pages.
225
+ const pages = [
226
+ ...oldData.pages
227
+ ];
228
+ const firstPageItems = pages?.[0]?.orderedItems || pages?.[0]?.items || [];
229
+ firstPageItems.unshift(item);
230
+ oldData.pages = pages;
231
+ return oldData;
232
+ });
233
+ if (shouldRefetch) setTimeout(()=>queryClient.refetchQueries([
234
+ "collection",
235
+ {
236
+ collectionUrl: collectionUrl
237
+ }
238
+ ], {
239
+ active: true,
240
+ exact: true
241
+ }), typeof shouldRefetch === "number" ? shouldRefetch : 2000);
242
+ }, [
243
+ queryClient,
244
+ collectionUrl
245
+ ]);
246
+ const removeItem = (0, $85cNH$useCallback)((item, shouldRefetch = true)=>{
247
+ queryClient.setQueryData([
248
+ "collection",
249
+ {
250
+ collectionUrl: collectionUrl
251
+ }
252
+ ], (oldData)=>{
253
+ if (!oldData) return oldData;
254
+ setTotalItems(totalItems && totalItems - 1);
255
+ // Destructure, so react knows, it needs to re-render the pages array.
256
+ const pages = [
257
+ ...oldData.pages
258
+ ];
259
+ // Find the item in all pages and remove the item to be removed (either item.id or just item)
260
+ pages.forEach((page)=>{
261
+ if (page.orderedItems) page.orderedItems = page.orderedItems.filter((i)=>(i.id || i) !== (item.id || item));
262
+ else if (page.items) page.items = page.items.filter((i)=>(i.id || i) !== (item?.id || item));
263
+ });
264
+ oldData.pages = pages;
265
+ return oldData;
266
+ });
267
+ if (shouldRefetch) setTimeout(()=>queryClient.refetchQueries([
268
+ "collection",
269
+ {
270
+ collectionUrl: collectionUrl
271
+ }
272
+ ], {
273
+ active: true,
274
+ exact: true
275
+ }), typeof shouldRefetch === "number" ? shouldRefetch : 2000);
276
+ }, [
277
+ queryClient,
278
+ collectionUrl
279
+ ]);
280
+ // Live Updates
281
+ (0, $85cNH$useEffect)(()=>{
282
+ if (liveUpdates && collectionUrl) // Create ws that listens to collectionUri changes
283
+ (0, $85cNH$getOrCreateWsChannel)(dataProvider.fetch, collectionUrl).then((webSocket)=>{
284
+ webSocket.addEventListener("message", (e)=>{
285
+ const data = JSON.parse(e.data);
286
+ if (data.type === "Add") addItem(data.object, true);
287
+ else if (data.type === "Remove") removeItem(data.object, true);
288
+ });
289
+ webSocket.addEventListener("error", (e)=>{
290
+ setHasLiveUpdates({
291
+ status: "error",
292
+ error: e
293
+ });
294
+ // TODO: Retry after a while
295
+ });
296
+ webSocket.addEventListener("close", (e)=>{
297
+ if (!hasLiveUpdates.error) setHasLiveUpdates({
298
+ ...hasLiveUpdates,
299
+ status: "closed"
300
+ });
301
+ });
302
+ setHasLiveUpdates({
303
+ status: "connected",
304
+ webSocket: webSocket
305
+ });
306
+ }).catch(()=>{}); // If it fails, we won't receive live updates. But that's okay.
307
+ }, [
308
+ collectionUrl,
309
+ liveUpdates,
310
+ dataProvider
95
311
  ]);
96
- const sparqlEndpoint = (0, $85cNH$useMemo)(()=>{
97
- if (identity?.webIdData) return identity?.webIdData?.endpoints?.["void:sparqlEndpoint"] || `${identity?.id}/sparql`;
312
+ return {
313
+ items: items,
314
+ totalItems: totalItems,
315
+ error: allErrors.length > 0 && allErrors,
316
+ refetch: refetch,
317
+ fetchNextPage: fetchNextPage,
318
+ addItem: addItem,
319
+ removeItem: removeItem,
320
+ hasNextPage: hasNextPage,
321
+ isLoading: isLoadingPage || isLoadingItems,
322
+ isFetching: isFetchingPage || isFetchingItems,
323
+ isFetchingNextPage: isFetchingNextPage,
324
+ url: collectionUrl,
325
+ hasLiveUpdates: hasLiveUpdates
326
+ };
327
+ };
328
+ var $8281f3ce3b9d6123$export$2e2bcd8739ae039 = $8281f3ce3b9d6123$var$useCollection;
329
+
330
+
331
+
332
+
333
+ /**
334
+ * Hook used internally by useInbox and useOutbox. This is not exported.
335
+ * @param webSocket WebSocket which allow to listen to the inbox or outbox
336
+ * @param existingActivities Partial list of activities already received in the inbox and outbox
337
+ */ const $600ca419166a1ded$var$useAwaitActivity = (webSocket, existingActivities)=>{
338
+ 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
340
+ return (0, $85cNH$useCallback)((matchActivity, options = {})=>{
341
+ const { timeout: timeout = 30000, checkExistingActivities: checkExistingActivities = false } = options;
342
+ return new Promise((resolve, reject)=>{
343
+ if (webSocket) {
344
+ const onMessage = (event)=>{
345
+ const data = JSON.parse(event.data);
346
+ if (data.type === "Add") dataProvider.fetch(data.object).then(({ json: json })=>{
347
+ if (matchActivity(json)) {
348
+ webSocket.removeEventListener("message", onMessage);
349
+ return resolve(json);
350
+ }
351
+ });
352
+ };
353
+ webSocket.addEventListener("message", onMessage);
354
+ // TODO reconnect if connection closed
355
+ webSocket.addEventListener("error", (e)=>{
356
+ reject(e);
357
+ });
358
+ webSocket.addEventListener("close", (e)=>{
359
+ reject(new Error(`${e.reason} (Code: ${e.code})`));
360
+ });
361
+ // If a list of activities is already loaded, verify if there is a match
362
+ if (existingActivities && checkExistingActivities) for (const a of existingActivities){
363
+ if (typeof a !== "string") {
364
+ if (matchActivity(a)) {
365
+ webSocket.removeEventListener("message", onMessage);
366
+ return resolve(a);
367
+ }
368
+ }
369
+ }
370
+ setTimeout(()=>{
371
+ webSocket.removeEventListener("message", onMessage);
372
+ reject(new Error("Timeout"));
373
+ }, timeout);
374
+ } else throw new Error("WebSocket is not initialized !");
375
+ });
98
376
  }, [
99
- identity
377
+ webSocket,
378
+ existingActivities,
379
+ dataProvider
100
380
  ]);
381
+ };
382
+ var $600ca419166a1ded$export$2e2bcd8739ae039 = $600ca419166a1ded$var$useAwaitActivity;
383
+
384
+
385
+ /**
386
+ * Hook to fetch and post to the outbox of the logged user.
387
+ * Returns the same data as the useCollection hooks, plus:
388
+ * - `post`: a function to post a new activity in the user's outbox
389
+ * - `awaitActivity`: a function to wait for a certain activity to be posted
390
+ * - `owner`: the WebID of the outbox's owner
391
+ * See https://semapps.org/docs/frontend/activitypub-components#useoutbox for usage
392
+ * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: true }`
393
+ */ const $4d1d40fdbcd30589$var$useOutbox = (options = {})=>{
394
+ const dataProvider = (0, $85cNH$useDataProvider)();
395
+ 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);
101
398
  // Post an activity to the logged user's outbox and return its URI
102
399
  const post = (0, $85cNH$useCallback)(async (activity)=>{
103
- if (!outboxUrl) throw new Error("Cannot post to outbox before user identity is loaded. Please use the loaded argument of useOutbox");
104
- const token = localStorage.getItem("token");
105
- const { headers: headers } = await (0, $85cNH$fetchUtils).fetchJson(outboxUrl, {
400
+ if (!url) throw new Error("Cannot post to outbox before user identity is loaded. Please use the isLoading argument of useOutbox");
401
+ const { headers: headers } = await dataProvider.fetch(url, {
106
402
  method: "POST",
107
403
  body: JSON.stringify({
108
404
  "@context": "https://www.w3.org/ns/activitystreams",
109
405
  ...activity
110
- }),
111
- headers: new Headers({
112
- "Content-Type": "application/ld+json",
113
- Authorization: `Bearer ${token}`
114
406
  })
115
407
  });
116
408
  return headers.get("Location");
117
409
  }, [
118
- outboxUrl
119
- ]);
120
- const fetch = (0, $85cNH$useCallback)(async ()=>{
121
- if (!sparqlEndpoint || !outboxUrl) return;
122
- const token = localStorage.getItem("token");
123
- const blankNodesQuery = (0, $85cNH$buildBlankNodesQuery)([
124
- "as:object"
125
- ]);
126
- const query = `
127
- PREFIX as: <https://www.w3.org/ns/activitystreams#>
128
- CONSTRUCT {
129
- ?s1 ?p1 ?o1 .
130
- ${blankNodesQuery.construct}
131
- }
132
- WHERE {
133
- <${outboxUrl}> as:items ?s1 .
134
- ?s1 ?p1 ?o1 .
135
- ${blankNodesQuery.where}
136
- }
137
- `;
138
- const { json: json } = await (0, $85cNH$fetchUtils).fetchJson(sparqlEndpoint, {
139
- method: "POST",
140
- body: query,
141
- headers: new Headers({
142
- Accept: "application/ld+json",
143
- Authorization: token ? `Bearer ${token}` : undefined
144
- })
145
- });
146
- if (json["@graph"]) return json["@graph"];
147
- return null;
148
- }, [
149
- sparqlEndpoint,
150
- outboxUrl
410
+ url,
411
+ dataProvider
151
412
  ]);
152
413
  return {
414
+ url: url,
415
+ hasLiveUpdates: hasLiveUpdates,
416
+ items: items,
153
417
  post: post,
154
- fetch: fetch,
155
- url: outboxUrl,
156
- loaded: !!outboxUrl,
157
- owner: identity?.id
418
+ awaitActivity: awaitActivity,
419
+ owner: identity?.id,
420
+ ...rest
158
421
  };
159
422
  };
160
- var $712f7f004b5f345e$export$2e2bcd8739ae039 = $712f7f004b5f345e$var$useOutbox;
423
+ var $4d1d40fdbcd30589$export$2e2bcd8739ae039 = $4d1d40fdbcd30589$var$useOutbox;
161
424
 
162
425
 
163
426
 
@@ -262,7 +525,7 @@ const $3c17312a40ebf1ed$var$PostCommentForm = ({ context: context, placeholder:
262
525
  const userDataModel = (0, $85cNH$useDataModel)(userResource);
263
526
  const classes = $3c17312a40ebf1ed$var$useStyles();
264
527
  const notify = (0, $85cNH$useNotify)();
265
- const outbox = (0, $712f7f004b5f345e$export$2e2bcd8739ae039)();
528
+ const outbox = (0, $4d1d40fdbcd30589$export$2e2bcd8739ae039)();
266
529
  const [expanded, setExpanded] = (0, $85cNH$useState)(false);
267
530
  const [openAuth, setOpenAuth] = (0, $85cNH$useState)(false);
268
531
  const onSubmit = (0, $85cNH$useCallback)(async (values)=>{
@@ -491,217 +754,40 @@ const $be88b298220210d1$var$CommentsList = ({ comments: comments, userResource:
491
754
  variant: "body2",
492
755
  source: "published",
493
756
  showTime: true
494
- })
495
- ]
496
- }),
497
- /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$RichTextField), {
498
- record: comment,
499
- variant: "body1",
500
- source: "content",
501
- className: classes.content
502
- })
503
- ]
504
- })
505
- ]
506
- }, comment.id)),
507
- loading && /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$Box), {
508
- minHeight: 200,
509
- children: /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$Box), {
510
- alignItems: "center",
511
- className: classes.loading,
512
- children: /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$CircularProgress), {
513
- size: 60,
514
- thickness: 6
515
- })
516
- })
517
- })
518
- ]
519
- });
520
- };
521
- var $be88b298220210d1$export$2e2bcd8739ae039 = $be88b298220210d1$var$CommentsList;
522
-
523
-
524
-
525
-
526
-
527
-
528
- const $577f4953dfa5de4f$export$e57ff0f701c44363 = (value)=>{
529
- // If the field is null-ish, we suppose there are no values.
530
- if (value === null || value === undefined) return [];
531
- // Return as is.
532
- if (Array.isArray(value)) return value;
533
- // Single value is made an array.
534
- return [
535
- value
536
- ];
537
- };
538
- var $577f4953dfa5de4f$export$2e2bcd8739ae039 = {
539
- arrayOf: $577f4953dfa5de4f$export$e57ff0f701c44363
540
- };
541
- const $577f4953dfa5de4f$export$34aed805e991a647 = (iterable, predicate)=>{
542
- const seen = new Set();
543
- return iterable.filter((item)=>{
544
- const key = predicate(item);
545
- if (seen.has(key)) return false;
546
- seen.add(key);
547
- return true;
548
- });
549
- };
550
-
551
-
552
- const $c1e897431d8c5742$var$useItemsFromPagesAndNotifications = (pages, notifications, dereferenceItems)=>{
553
- const dataProvider = (0, $85cNH$useDataProvider)();
554
- // Add all items from pages and process notifications (possibly new and deleted items).
555
- const items = (0, $85cNH$useMemo)(()=>{
556
- const addItems = notifications.map((n)=>n.type === "Add").map((n)=>n.object);
557
- const removeItems = notifications.map((n)=>n.type === "Remove").map((n)=>n.object.id || n.object);
558
- const currentItems = !pages ? [] : pages.flatMap((p)=>(0, $577f4953dfa5de4f$export$e57ff0f701c44363)(p.orderedItems || p.items));
559
- const currentAndNew = currentItems.concat(addItems);
560
- return currentAndNew// Filter out removed items.
561
- .filter((item)=>!removeItems.some((r)=>(r.id ?? r) === (item.id ?? item)))// Filter duplicates.
562
- .filter((item)=>currentAndNew.some((i2)=>(i2.id ?? i2) === (item.id ?? item)));
563
- }, pages, notifications);
564
- if (!dereferenceItems) return {
565
- loadedItems: items,
566
- isLoading: false,
567
- isFetching: false
568
- };
569
- // Dereference all items, if they are not yet.
570
- const itemQueries = (0, $85cNH$useQueries)(items.filter((item)=>typeof item === "string").map((itemUri)=>({
571
- queryKey: [
572
- "resource",
573
- itemUri
574
- ],
575
- queryFn: async ()=>(await dataProvider.fetch(itemUri)).json,
576
- staleTime: Infinity
577
- })));
578
- // Put all loaded items together (might be dereferenced already, so concatenate).
579
- const loadedItems = items.filter((item)=>typeof item !== "string").concat(itemQueries.flatMap((itemQuery)=>{
580
- return itemQuery.isSuccess && itemQuery.data || [];
581
- }));
582
- console.log("loadedItems", loadedItems.length, "total", items.length);
583
- const errors = itemQueries.filter((q)=>q.error);
584
- return {
585
- loadedItems: loadedItems,
586
- isLoading: itemQueries.some((q)=>q.isLoading),
587
- isFetching: itemQueries.some((q)=>q.isFetching),
588
- errors: errors.length > 0 && errors
589
- };
590
- };
591
- const $c1e897431d8c5742$var$useCollection = (predicateOrUrl, options = {})=>{
592
- const { dereferenceItems: dereferenceItems = false, liveUpdates: liveUpdates = true } = options;
593
- const { data: identity } = (0, $85cNH$useGetIdentity)();
594
- const [totalItems, setTotalItems] = (0, $85cNH$useState)();
595
- const [notifications, setNotifications] = (0, $85cNH$useState)([]);
596
- const [hasLiveUpdates, setHasLiveUpdates] = (0, $85cNH$useState)({
597
- status: "disconnected",
598
- error: undefined
599
- });
600
- const dataProvider = (0, $85cNH$useDataProvider)();
601
- // Get collectionUrl from webId predicate or URL.
602
- const collectionUrl = (0, $85cNH$useMemo)(()=>{
603
- if (predicateOrUrl) {
604
- if (predicateOrUrl.startsWith("http")) return predicateOrUrl;
605
- if (identity?.webIdData) return identity?.webIdData?.[predicateOrUrl];
606
- }
607
- return undefined;
608
- // throw new Error(`No URL available for useCollection: ${predicateOrUrl}.`);
609
- }, [
610
- identity,
611
- predicateOrUrl
612
- ]);
613
- // Fetch page of collection item references (if pageParam provided)
614
- // or default to `collectionUrl` (which should give you the first page).
615
- const fetchCollection = (0, $85cNH$useCallback)(async ({ pageParam: nextPageUrl })=>{
616
- // Fetch page or first page (collectionUrl)
617
- let { json: json } = await dataProvider.fetch(nextPageUrl || collectionUrl);
618
- if (json.totalItems) setTotalItems(json.totalItems);
619
- // If first page, handle this here.
620
- if ((json.type === "OrderedCollection" || json.type === "Collection") && json.first) {
621
- if (json.first?.items) {
622
- if (json.first?.items.length === 0 && json.first?.next) // Special case where the first property is an object without items
623
- ({ json: json } = await dataProvider.fetch(json.first?.next));
624
- else json = json.first;
625
- } else // Fetch the first page
626
- ({ json: json } = await dataProvider.fetch(json.first));
627
- }
628
- return json;
629
- }, [
630
- dataProvider,
631
- collectionUrl,
632
- identity,
633
- setTotalItems
634
- ]);
635
- // Use infiniteQuery to handle pagination, fetching, etc.
636
- const { data: data, error: collectionError, fetchNextPage: fetchNextPage, refetch: refetch, hasNextPage: hasNextPage, isLoading: isLoadingPage, isFetching: isFetchingPage, isFetchingNextPage: isFetchingNextPage } = (0, $85cNH$useInfiniteQuery)([
637
- "collection",
638
- {
639
- collectionUrl: collectionUrl
640
- }
641
- ], fetchCollection, {
642
- enabled: !!(collectionUrl && identity?.id),
643
- getNextPageParam: (lastPage)=>lastPage.next,
644
- getPreviousPageParam: (firstPage)=>firstPage.prev
645
- });
646
- // Put all items together in a list.
647
- const { loadedItems: items, isLoading: isLoadingItems, isFetching: isFetchingItems, errors: itemErrors } = $c1e897431d8c5742$var$useItemsFromPagesAndNotifications(data?.pages, notifications, dereferenceItems);
648
- // Notifications have been processed after hook call, so reset.
649
- // useEffect(() => {
650
- // setNotifications([]);
651
- // }, [notifications])
652
- // Live Updates
653
- (0, $85cNH$useEffect)(()=>{
654
- if (liveUpdates && collectionUrl) // Create ws that listens to collectionUri changes
655
- (0, $85cNH$getOrCreateWsChannel)(dataProvider.fetch, collectionUrl).then((webSocket)=>{
656
- webSocket.addEventListener("message", (e)=>{
657
- if (e.data && e.data.type === "Add" || e.data.type === "Remove") setNotifications([
658
- ...notifications,
659
- e.data
660
- ]);
661
- });
662
- webSocket.addEventListener("error", (e)=>{
663
- setHasLiveUpdates({
664
- status: "error",
665
- error: e
666
- });
667
- // TODO: Retry after a while
668
- });
669
- webSocket.addEventListener("close", (e)=>{
670
- setHasLiveUpdates({
671
- ...hasLiveUpdates,
672
- status: "disconnected"
673
- });
674
- });
675
- setHasLiveUpdates({
676
- status: "connected"
677
- });
678
- }).catch(()=>{}); // If it fails, we won't receive live updates. But that's okay.
679
- }, [
680
- collectionUrl,
681
- liveUpdates,
682
- dataProvider.fetch
683
- ]);
684
- const allErrors = (0, $577f4953dfa5de4f$export$e57ff0f701c44363)(collectionError).concat((0, $577f4953dfa5de4f$export$e57ff0f701c44363)(itemErrors));
685
- return {
686
- items: items,
687
- totalItems: totalItems,
688
- error: allErrors.length > 0 && allErrors,
689
- refetch: refetch,
690
- fetchNextPage: fetchNextPage,
691
- hasNextPage: hasNextPage,
692
- isLoading: isLoadingPage || isLoadingItems,
693
- isFetching: isFetchingPage || isFetchingItems,
694
- isFetchingNextPage: isFetchingNextPage,
695
- url: collectionUrl,
696
- hasLiveUpdates: hasLiveUpdates
697
- };
757
+ })
758
+ ]
759
+ }),
760
+ /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$RichTextField), {
761
+ record: comment,
762
+ variant: "body1",
763
+ source: "content",
764
+ className: classes.content
765
+ })
766
+ ]
767
+ })
768
+ ]
769
+ }, comment.id)),
770
+ loading && /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$Box), {
771
+ minHeight: 200,
772
+ children: /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$Box), {
773
+ alignItems: "center",
774
+ className: classes.loading,
775
+ children: /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$CircularProgress), {
776
+ size: 60,
777
+ thickness: 6
778
+ })
779
+ })
780
+ })
781
+ ]
782
+ });
698
783
  };
699
- var $c1e897431d8c5742$export$2e2bcd8739ae039 = $c1e897431d8c5742$var$useCollection;
784
+ var $be88b298220210d1$export$2e2bcd8739ae039 = $be88b298220210d1$var$CommentsList;
785
+
700
786
 
701
787
 
702
788
  const $7ce737d4a1c88e63$var$CommentsField = ({ source: source, context: context, helperText: helperText, placeholder: placeholder, userResource: userResource, mentions: mentions })=>{
703
789
  const record = (0, $85cNH$useRecordContext)();
704
- const { items: comments, loading: loading, addItem: addItem, removeItem: removeItem } = (0, $c1e897431d8c5742$export$2e2bcd8739ae039)(record.replies);
790
+ const { items: comments, loading: loading, addItem: addItem, removeItem: removeItem } = (0, $8281f3ce3b9d6123$export$2e2bcd8739ae039)(record.replies);
705
791
  if (!userResource) throw new Error("No userResource defined for CommentsField");
706
792
  return /*#__PURE__*/ (0, $85cNH$jsxs)((0, $85cNH$Fragment), {
707
793
  children: [
@@ -737,7 +823,7 @@ var $7ce737d4a1c88e63$export$2e2bcd8739ae039 = $7ce737d4a1c88e63$var$CommentsFie
737
823
 
738
824
  const $d3be168cd1e7aaae$var$CollectionList = ({ collectionUrl: collectionUrl, resource: resource, children: children })=>{
739
825
  if ((0, $85cNH$react).Children.count(children) !== 1) throw new Error("<CollectionList> only accepts a single child");
740
- const { items: actorsUris } = (0, $c1e897431d8c5742$export$2e2bcd8739ae039)(collectionUrl);
826
+ const { items: actorsUris } = (0, $8281f3ce3b9d6123$export$2e2bcd8739ae039)(collectionUrl);
741
827
  const { data: data, isLoading: isLoading, isFetching: isFetching } = (0, $85cNH$useGetMany)(resource, {
742
828
  ids: Array.isArray(actorsUris) ? actorsUris : [
743
829
  actorsUris
@@ -780,302 +866,49 @@ var $ea214512ab1a2e8f$export$2e2bcd8739ae039 = $ea214512ab1a2e8f$var$ReferenceCo
780
866
 
781
867
 
782
868
 
783
-
784
- const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
785
- const dataProvider = (0, $85cNH$useDataProvider)();
786
- const items = (0, $85cNH$useMemo)(()=>pages.flatMap((p)=>(0, $577f4953dfa5de4f$export$e57ff0f701c44363)(p.orderedItems || p.items)), [
787
- pages
788
- ]);
789
- // We will force dereference, if some items are not URI string references.
790
- const shouldDereference = (0, $85cNH$useMemo)(()=>{
791
- return dereferenceItems || items.some((item)=>typeof item !== "string");
792
- }, [
793
- dereferenceItems,
794
- items
795
- ]);
796
- // Dereference all items, if necessary (even if shouldDereference is false, the hook needs to be called).
797
- const itemQueries = (0, $85cNH$useQueries)(!shouldDereference ? [] : items.filter((item)=>typeof item === "string").map((itemUri)=>({
798
- queryKey: [
799
- "resource",
800
- itemUri
801
- ],
802
- queryFn: async ()=>(await dataProvider.fetch(itemUri)).json,
803
- staleTime: Infinity
804
- })));
805
- if (!shouldDereference) return {
806
- loadedItems: items,
807
- isLoading: false,
808
- isFetching: false
809
- };
810
- // Put all loaded items together (might be dereferenced already, so concatenate).
811
- const loadedItems = items.filter((item)=>typeof item !== "string").concat(itemQueries.flatMap((itemQuery)=>{
812
- return itemQuery.isSuccess && itemQuery.data || [];
813
- }));
814
- const errors = itemQueries.filter((q)=>q.error);
815
- return {
816
- loadedItems: loadedItems,
817
- isLoading: itemQueries.some((q)=>q.isLoading),
818
- isFetching: itemQueries.some((q)=>q.isFetching),
819
- errors: errors.length > 0 ? errors : undefined
820
- };
821
- };
822
869
  /**
823
- * Subscribe a collection. Supports pagination.
824
- * @param predicateOrUrl The collection URI or the predicate to get the collection URI from the identity (webId).
870
+ * Hook to fetch the inbox of the logged user.
871
+ * Returns the same data as the useCollection hooks, plus:
872
+ * - `awaitActivity`: a function to wait for a certain activity to be received
873
+ * - `owner`: the WebID of the inbox's owner
874
+ * See https://semapps.org/docs/frontend/activitypub-components#useinbox for usage
825
875
  * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: true }`
826
- */ const $8281f3ce3b9d6123$var$useCollection = (predicateOrUrl, options = {})=>{
827
- const { dereferenceItems: dereferenceItems = false, liveUpdates: liveUpdates = true } = options;
876
+ */ const $cc1d1cd0e97c63a2$var$useInbox = (options = {})=>{
828
877
  const { data: identity } = (0, $85cNH$useGetIdentity)();
829
- const [totalItems, setTotalItems] = (0, $85cNH$useState)();
830
- const queryClient = (0, $85cNH$useQueryClient)();
831
- const [hasLiveUpdates, setHasLiveUpdates] = (0, $85cNH$useState)({
832
- status: "connecting"
833
- });
834
- const dataProvider = (0, $85cNH$useDataProvider)();
835
- // Get collectionUrl from webId predicate or URL.
836
- const collectionUrl = (0, $85cNH$useMemo)(()=>{
837
- if (predicateOrUrl) {
838
- if (predicateOrUrl.startsWith("http")) return predicateOrUrl;
839
- if (identity?.webIdData) return identity?.webIdData?.[predicateOrUrl];
840
- }
841
- return undefined;
842
- // throw new Error(`No URL available for useCollection: ${predicateOrUrl}.`);
843
- }, [
844
- identity,
845
- predicateOrUrl
846
- ]);
847
- // Fetch page of collection item references (if pageParam provided)
848
- // or default to `collectionUrl` (which should give you the first page).
849
- const fetchCollection = (0, $85cNH$useCallback)(async ({ pageParam: nextPageUrl })=>{
850
- // Fetch page or first page (collectionUrl)
851
- let { json: json } = await dataProvider.fetch(nextPageUrl || collectionUrl);
852
- if (json.totalItems) setTotalItems(json.totalItems);
853
- // If first page, handle this here.
854
- if ((json.type === "OrderedCollection" || json.type === "Collection") && json.first) {
855
- if (json.first?.items) {
856
- if (json.first?.items.length === 0 && json.first?.next) // Special case where the first property is an object without items
857
- ({ json: json } = await dataProvider.fetch(json.first?.next));
858
- else json = json.first;
859
- } else // Fetch the first page
860
- ({ json: json } = await dataProvider.fetch(json.first));
861
- }
862
- return json;
863
- }, [
864
- dataProvider,
865
- collectionUrl,
866
- identity,
867
- setTotalItems
868
- ]);
869
- // Use infiniteQuery to handle pagination, fetching, etc.
870
- const { data: pageData, error: collectionError, fetchNextPage: fetchNextPage, refetch: refetch, hasNextPage: hasNextPage, isLoading: isLoadingPage, isFetching: isFetchingPage, isFetchingNextPage: isFetchingNextPage } = (0, $85cNH$useInfiniteQuery)([
871
- "collection",
872
- {
873
- collectionUrl: collectionUrl
874
- }
875
- ], fetchCollection, {
876
- enabled: !!(collectionUrl && identity?.id),
877
- getNextPageParam: (lastPage)=>lastPage.next,
878
- getPreviousPageParam: (firstPage)=>firstPage.prev
879
- });
880
- // Put all items together in a list (and dereference, if required).
881
- const { loadedItems: items, isLoading: isLoadingItems, isFetching: isFetchingItems, errors: itemErrors } = $8281f3ce3b9d6123$var$useItemsFromPages(pageData?.pages ?? [], dereferenceItems);
882
- const allErrors = (0, $577f4953dfa5de4f$export$e57ff0f701c44363)(collectionError).concat((0, $577f4953dfa5de4f$export$e57ff0f701c44363)(itemErrors));
883
- const addItem = (0, $85cNH$useCallback)((item, shouldRefetch = true)=>{
884
- queryClient.setQueryData([
885
- "collection",
886
- {
887
- collectionUrl: collectionUrl
888
- }
889
- ], (oldData)=>{
890
- if (!oldData) return oldData;
891
- setTotalItems(totalItems && totalItems + 1);
892
- // Destructure, so react knows, it needs to re-render the pages.
893
- const pages = [
894
- ...oldData.pages
895
- ];
896
- const firstPageItems = pages?.[0]?.orderedItems || pages?.[0]?.items || [];
897
- firstPageItems.unshift(item);
898
- oldData.pages = pages;
899
- return oldData;
900
- });
901
- if (shouldRefetch) setTimeout(()=>queryClient.refetchQueries([
902
- "collection",
903
- {
904
- collectionUrl: collectionUrl
905
- }
906
- ], {
907
- active: true,
908
- exact: true
909
- }), typeof shouldRefetch === "number" ? shouldRefetch : 2000);
910
- }, [
911
- queryClient,
912
- collectionUrl
913
- ]);
914
- const removeItem = (0, $85cNH$useCallback)((item, shouldRefetch = true)=>{
915
- queryClient.setQueryData([
916
- "collection",
917
- {
918
- collectionUrl: collectionUrl
919
- }
920
- ], (oldData)=>{
921
- if (!oldData) return oldData;
922
- setTotalItems(totalItems && totalItems - 1);
923
- // Destructure, so react knows, it needs to re-render the pages array.
924
- const pages = [
925
- ...oldData.pages
926
- ];
927
- // Find the item in all pages and remove the item to be removed (either item.id or just item)
928
- pages.forEach((page)=>{
929
- if (page.orderedItems) page.orderedItems = page.orderedItems.filter((i)=>(i.id || i) !== (item.id || item));
930
- else if (page.items) page.items = page.items.filter((i)=>(i.id || i) !== (item?.id || item));
931
- });
932
- oldData.pages = pages;
933
- return oldData;
934
- });
935
- if (shouldRefetch) setTimeout(()=>queryClient.refetchQueries([
936
- "collection",
937
- {
938
- collectionUrl: collectionUrl
939
- }
940
- ], {
941
- active: true,
942
- exact: true
943
- }), typeof shouldRefetch === "number" ? shouldRefetch : 2000);
944
- }, [
945
- queryClient,
946
- collectionUrl
947
- ]);
948
- // Live Updates
949
- (0, $85cNH$useEffect)(()=>{
950
- if (liveUpdates && collectionUrl) // Create ws that listens to collectionUri changes
951
- (0, $85cNH$getOrCreateWsChannel)(dataProvider.fetch, collectionUrl).then((webSocket)=>{
952
- webSocket.addEventListener("message", (e)=>{
953
- const data = JSON.parse(e.data);
954
- if (data && data.type === "Add") addItem(data.object, true);
955
- else if (data && data.type === "Remove") removeItem(data.object, true);
956
- });
957
- webSocket.addEventListener("error", (e)=>{
958
- setHasLiveUpdates({
959
- status: "error",
960
- error: e
961
- });
962
- // TODO: Retry after a while
963
- });
964
- webSocket.addEventListener("close", (e)=>{
965
- if (!hasLiveUpdates.error) setHasLiveUpdates({
966
- ...hasLiveUpdates,
967
- status: "closed"
968
- });
969
- });
970
- setHasLiveUpdates({
971
- status: "connected"
972
- });
973
- }).catch(()=>{}); // If it fails, we won't receive live updates. But that's okay.
974
- }, [
975
- collectionUrl,
976
- liveUpdates,
977
- dataProvider
978
- ]);
878
+ const { items: items, url: url, hasLiveUpdates: hasLiveUpdates, ...rest } = (0, $8281f3ce3b9d6123$export$2e2bcd8739ae039)("inbox", options);
879
+ const awaitActivity = (0, $600ca419166a1ded$export$2e2bcd8739ae039)(hasLiveUpdates.webSocket);
979
880
  return {
980
881
  items: items,
981
- totalItems: totalItems,
982
- error: allErrors.length > 0 && allErrors,
983
- refetch: refetch,
984
- fetchNextPage: fetchNextPage,
985
- addItem: addItem,
986
- removeItem: removeItem,
987
- hasNextPage: hasNextPage,
988
- isLoading: isLoadingPage || isLoadingItems,
989
- isFetching: isFetchingPage || isFetchingItems,
990
- isFetchingNextPage: isFetchingNextPage,
991
- url: collectionUrl,
992
- hasLiveUpdates: hasLiveUpdates
993
- };
994
- };
995
- var $8281f3ce3b9d6123$export$2e2bcd8739ae039 = $8281f3ce3b9d6123$var$useCollection;
996
-
997
-
998
-
999
-
1000
-
1001
- const $542b37cc25b8ccca$var$useInbox = ()=>{
1002
- const { data: identity } = (0, $85cNH$useGetIdentity)();
1003
- const inboxUrl = (0, $85cNH$useMemo)(()=>{
1004
- if (identity?.webIdData) return identity?.webIdData?.inbox;
1005
- }, [
1006
- identity
1007
- ]);
1008
- const sparqlEndpoint = (0, $85cNH$useMemo)(()=>{
1009
- if (identity?.webIdData) return identity?.webIdData?.endpoints?.["void:sparqlEndpoint"] || `${identity?.id}/sparql`;
1010
- }, [
1011
- identity
1012
- ]);
1013
- const fetch = (0, $85cNH$useCallback)(async ({ filters: filters })=>{
1014
- if (!sparqlEndpoint || !inboxUrl) return;
1015
- const token = localStorage.getItem("token");
1016
- const blankNodesQuery = (0, $85cNH$buildBlankNodesQuery)([
1017
- "as:object"
1018
- ]);
1019
- let filtersWhereQuery = "";
1020
- if (filters) Object.keys(filters).forEach((predicate)=>{
1021
- if (filters[predicate]) {
1022
- const object = filters[predicate].startsWith("http") ? `<${filters[predicate]}>` : filters[predicate];
1023
- filtersWhereQuery += `?s1 ${predicate} ${object} .`;
1024
- }
1025
- });
1026
- const query = `
1027
- PREFIX as: <https://www.w3.org/ns/activitystreams#>
1028
- CONSTRUCT {
1029
- ?s1 ?p1 ?o1 .
1030
- ${blankNodesQuery.construct}
1031
- }
1032
- WHERE {
1033
- <${inboxUrl}> as:items ?s1 .
1034
- ?s1 ?p1 ?o1 .
1035
- FILTER( (isIRI(?s1)) ) .
1036
- ${filtersWhereQuery}
1037
- ${blankNodesQuery.where}
1038
- }
1039
- `;
1040
- const { json: json } = await (0, $85cNH$fetchUtils).fetchJson(sparqlEndpoint, {
1041
- method: "POST",
1042
- body: query,
1043
- headers: new Headers({
1044
- Accept: "application/ld+json",
1045
- Authorization: token ? `Bearer ${token}` : undefined
1046
- })
1047
- });
1048
- if (json["@graph"]) return json["@graph"];
1049
- return null;
1050
- }, [
1051
- sparqlEndpoint,
1052
- inboxUrl
1053
- ]);
1054
- return {
1055
- fetch: fetch,
1056
- url: inboxUrl,
1057
- owner: identity?.id
882
+ url: url,
883
+ hasLiveUpdates: hasLiveUpdates,
884
+ awaitActivity: awaitActivity,
885
+ owner: identity?.id,
886
+ ...rest
1058
887
  };
1059
888
  };
1060
- var $542b37cc25b8ccca$export$2e2bcd8739ae039 = $542b37cc25b8ccca$var$useInbox;
889
+ var $cc1d1cd0e97c63a2$export$2e2bcd8739ae039 = $cc1d1cd0e97c63a2$var$useInbox;
1061
890
 
1062
891
 
1063
892
 
1064
893
 
1065
- const $641e93142bcf5435$var$useNodeinfo = (host, rel = "http://nodeinfo.diaspora.software/ns/schema/2.1")=>{
894
+ const $6a227ddc2fd92a7a$var$useNodeinfo = (host, rel = "http://nodeinfo.diaspora.software/ns/schema/2.1")=>{
1066
895
  const [schema, setSchema] = (0, $85cNH$useState)();
1067
896
  (0, $85cNH$useEffect)(()=>{
1068
897
  (async ()=>{
1069
- const protocol = host.includes(":") ? "http" : "https"; // If the host has a port, we are likely on HTTP
1070
- const nodeinfoUrl = `${protocol}://${host}/.well-known/nodeinfo`;
1071
- try {
1072
- const { json: links } = await (0, $85cNH$fetchUtils).fetchJson(nodeinfoUrl);
1073
- // Accept any version of the nodeinfo protocol
1074
- const link = links?.links?.find((l)=>l.rel === rel);
1075
- const { json: json } = await (0, $85cNH$fetchUtils).fetchJson(link.href);
1076
- setSchema(json);
1077
- } catch (e) {
1078
- // Do nothing if nodeinfo can't be fetched
898
+ if (host && rel) {
899
+ const protocol = host.includes(":") ? "http" : "https"; // If the host has a port, we are likely on HTTP
900
+ const nodeinfoUrl = `${protocol}://${host}/.well-known/nodeinfo`;
901
+ try {
902
+ const { json: links } = await (0, $85cNH$fetchUtils).fetchJson(nodeinfoUrl);
903
+ // Accept any version of the nodeinfo protocol
904
+ const link = links?.links?.find((l)=>l.rel === rel);
905
+ if (link) {
906
+ const { json: json } = await (0, $85cNH$fetchUtils).fetchJson(link.href);
907
+ setSchema(json);
908
+ }
909
+ } catch (e) {
910
+ // Do nothing if nodeinfo can't be fetched
911
+ }
1079
912
  }
1080
913
  })();
1081
914
  }, [
@@ -1085,7 +918,7 @@ const $641e93142bcf5435$var$useNodeinfo = (host, rel = "http://nodeinfo.diaspora
1085
918
  ]);
1086
919
  return schema;
1087
920
  };
1088
- var $641e93142bcf5435$export$2e2bcd8739ae039 = $641e93142bcf5435$var$useNodeinfo;
921
+ var $6a227ddc2fd92a7a$export$2e2bcd8739ae039 = $6a227ddc2fd92a7a$var$useNodeinfo;
1089
922
 
1090
923
 
1091
924
 
@@ -1279,5 +1112,5 @@ var $51cccd331ea8b13d$export$2e2bcd8739ae039 = $51cccd331ea8b13d$var$useMentions
1279
1112
 
1280
1113
 
1281
1114
 
1282
- export {$7ce737d4a1c88e63$export$2e2bcd8739ae039 as CommentsField, $d3be168cd1e7aaae$export$2e2bcd8739ae039 as CollectionList, $ea214512ab1a2e8f$export$2e2bcd8739ae039 as ReferenceCollectionField, $8281f3ce3b9d6123$export$2e2bcd8739ae039 as useCollection, $542b37cc25b8ccca$export$2e2bcd8739ae039 as useInbox, $641e93142bcf5435$export$2e2bcd8739ae039 as useNodeinfo, $712f7f004b5f345e$export$2e2bcd8739ae039 as useOutbox, $2514c63dc8f4867c$export$2e2bcd8739ae039 as useWebfinger, $51cccd331ea8b13d$export$2e2bcd8739ae039 as useMentions, $338f387df48a40d7$export$1ec8e53e7d982d22 as ACTIVITY_TYPES, $338f387df48a40d7$export$9649665d7ccb0dc2 as ACTOR_TYPES, $338f387df48a40d7$export$c49cfb2681596b20 as OBJECT_TYPES, $338f387df48a40d7$export$4d8d554031975581 as PUBLIC_URI};
1115
+ export {$7ce737d4a1c88e63$export$2e2bcd8739ae039 as CommentsField, $d3be168cd1e7aaae$export$2e2bcd8739ae039 as CollectionList, $ea214512ab1a2e8f$export$2e2bcd8739ae039 as ReferenceCollectionField, $8281f3ce3b9d6123$export$2e2bcd8739ae039 as useCollection, $cc1d1cd0e97c63a2$export$2e2bcd8739ae039 as useInbox, $6a227ddc2fd92a7a$export$2e2bcd8739ae039 as useNodeinfo, $4d1d40fdbcd30589$export$2e2bcd8739ae039 as useOutbox, $2514c63dc8f4867c$export$2e2bcd8739ae039 as useWebfinger, $51cccd331ea8b13d$export$2e2bcd8739ae039 as useMentions, $338f387df48a40d7$export$1ec8e53e7d982d22 as ACTIVITY_TYPES, $338f387df48a40d7$export$9649665d7ccb0dc2 as ACTOR_TYPES, $338f387df48a40d7$export$c49cfb2681596b20 as OBJECT_TYPES, $338f387df48a40d7$export$4d8d554031975581 as PUBLIC_URI};
1283
1116
  //# sourceMappingURL=index.es.js.map