@semapps/activitypub-components 1.1.3 → 1.2.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
@@ -4,19 +4,24 @@ import {useRecordContext as $85cNH$useRecordContext, useGetIdentity as $85cNH$us
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
- import $85cNH$muistylesmakeStyles from "@mui/styles/makeStyles";
7
+ import {makeStyles as $85cNH$makeStyles} from "tss-react/mui";
8
8
  import $85cNH$muiiconsmaterialSend from "@mui/icons-material/Send";
9
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";
12
- import $85cNH$rdfvalidateshacl from "rdf-validate-shacl";
11
+ import {useQueries as $85cNH$useQueries, useQueryClient as $85cNH$useQueryClient, useInfiniteQuery as $85cNH$useInfiniteQuery} from "@tanstack/react-query";
12
+ import $85cNH$jsonld from "jsonld";
13
13
  import $85cNH$rdfext from "rdf-ext";
14
- import $85cNH$rdfjsparserjsonld from "@rdfjs/parser-jsonld";
15
- import {ReadableWebToNodeStream as $85cNH$ReadableWebToNodeStream} from "readable-web-to-node-stream";
16
14
  import $85cNH$rdfjsparsern3 from "@rdfjs/parser-n3";
15
+ import {Readable as $85cNH$Readable} from "readable-stream";
16
+ import {Validator as $85cNH$Validator} from "shacl-engine";
17
+ import {jsonld as $85cNH$jsonld1} from "@activitypods/shape-definitions";
18
+ import {ReadableWebToNodeStream as $85cNH$ReadableWebToNodeStream} from "readable-web-to-node-stream";
17
19
  import {mergeAttributes as $85cNH$mergeAttributes} from "@tiptap/core";
18
20
  import $85cNH$tiptapextensionmention from "@tiptap/extension-mention";
19
21
  import {ReferenceField as $85cNH$ReferenceField, AvatarWithLabelField as $85cNH$AvatarWithLabelField} from "@semapps/field-components";
22
+ import {createConnectedLdoDataset as $85cNH$createConnectedLdoDataset} from "@ldo/connected";
23
+ import {solidConnectedPlugin as $85cNH$solidConnectedPlugin} from "@ldo/connected-solid";
24
+ import {OrderedCollectionPageShapeType as $85cNH$OrderedCollectionPageShapeType} from "@activitypods/ldo-shapes";
20
25
  import {ReactRenderer as $85cNH$ReactRenderer} from "@tiptap/react";
21
26
  import $85cNH$tippyjs from "tippy.js";
22
27
 
@@ -34,7 +39,7 @@ import $85cNH$tippyjs from "tippy.js";
34
39
 
35
40
 
36
41
 
37
- const $338f387df48a40d7$export$1ec8e53e7d982d22 = {
42
+ const $cb5f912aee8137fc$export$1ec8e53e7d982d22 = {
38
43
  ACCEPT: 'Accept',
39
44
  ADD: 'Add',
40
45
  ANNOUNCE: 'Announce',
@@ -64,14 +69,14 @@ const $338f387df48a40d7$export$1ec8e53e7d982d22 = {
64
69
  UPDATE: 'Update',
65
70
  VIEW: 'View'
66
71
  };
67
- const $338f387df48a40d7$export$9649665d7ccb0dc2 = {
72
+ const $cb5f912aee8137fc$export$9649665d7ccb0dc2 = {
68
73
  APPLICATION: 'Application',
69
74
  GROUP: 'Group',
70
75
  ORGANIZATION: 'Organization',
71
76
  PERSON: 'Person',
72
77
  SERVICE: 'Service'
73
78
  };
74
- const $338f387df48a40d7$export$c49cfb2681596b20 = {
79
+ const $cb5f912aee8137fc$export$c49cfb2681596b20 = {
75
80
  ARTICLE: 'Article',
76
81
  AUDIO: 'Audio',
77
82
  DOCUMENT: 'Document',
@@ -85,7 +90,11 @@ const $338f387df48a40d7$export$c49cfb2681596b20 = {
85
90
  TOMBSTONE: 'Tombstone',
86
91
  VIDEO: 'Video'
87
92
  };
88
- const $338f387df48a40d7$export$4d8d554031975581 = 'https://www.w3.org/ns/activitystreams#Public';
93
+ const $cb5f912aee8137fc$export$4d8d554031975581 = 'https://www.w3.org/ns/activitystreams#Public';
94
+
95
+
96
+
97
+
89
98
 
90
99
 
91
100
 
@@ -116,6 +125,45 @@ const $577f4953dfa5de4f$export$34aed805e991a647 = (iterable, predicate)=>{
116
125
  return true;
117
126
  });
118
127
  };
128
+ const $577f4953dfa5de4f$export$2684df65fa35e98e = async (jsonLdObject)=>{
129
+ // Convert JSON-LD object to N-Quads string
130
+ const nquads = await (0, $85cNH$jsonld).toRDF(jsonLdObject, {
131
+ format: 'application/n-quads'
132
+ });
133
+ // Parse N-Quads string to RDF/JS quads
134
+ const parser = new (0, $85cNH$rdfjsparsern3)();
135
+ const quadStream = parser.import((0, $85cNH$Readable).from([
136
+ nquads
137
+ ]));
138
+ const dataset = await (0, $85cNH$rdfext).dataset().import(quadStream);
139
+ return dataset;
140
+ };
141
+ const $577f4953dfa5de4f$export$7089f01fea2fc5c2 = async (jsonLdObject)=>{
142
+ // Convert JSON-LD object to N-Quads string
143
+ const nquads = await (0, $85cNH$jsonld).toRDF(jsonLdObject, {
144
+ format: 'application/n-quads'
145
+ });
146
+ // Parse N-Quads string to RDF/JS quads
147
+ const parser = new (0, $85cNH$rdfjsparsern3)();
148
+ const quadStream = parser.import((0, $85cNH$Readable).from([
149
+ nquads
150
+ ]));
151
+ // Convert the quad stream to an array of quads
152
+ const quads = [];
153
+ quadStream.on('data', (quad)=>{
154
+ quads.push(quad);
155
+ });
156
+ return new Promise((resolve, reject)=>{
157
+ quadStream.on('end', ()=>{
158
+ resolve(quads);
159
+ });
160
+ quadStream.on('error', (error)=>{
161
+ reject(error);
162
+ });
163
+ });
164
+ };
165
+
166
+
119
167
 
120
168
 
121
169
 
@@ -123,10 +171,8 @@ const $577f4953dfa5de4f$export$34aed805e991a647 = (iterable, predicate)=>{
123
171
 
124
172
 
125
173
 
126
- // Cache of SHACL validators
127
- const $25cb6caf33e2f460$var$validatorCache = {};
128
174
  // Helper function to convert a string to a Node.js Readable stream
129
- const $25cb6caf33e2f460$var$stringToStream = (str)=>{
175
+ const $58194f7610fd9353$export$7b2e5d6b7377fcaf = (str)=>{
130
176
  // Create a TextEncoder to convert string to Uint8Array
131
177
  const encoder = new TextEncoder();
132
178
  const uint8Array = encoder.encode(str);
@@ -140,82 +186,135 @@ const $25cb6caf33e2f460$var$stringToStream = (str)=>{
140
186
  // Convert the web ReadableStream to a Node.js Readable stream
141
187
  return new (0, $85cNH$ReadableWebToNodeStream)(readableStream);
142
188
  };
143
- // Helper function to parse JSON-LD and convert to RDF-ext quads
144
- const $25cb6caf33e2f460$export$2684df65fa35e98e = async (jsonLdObj, context)=>{
189
+ const $58194f7610fd9353$export$7304a15200aa09e5 = async (turtleData)=>{
190
+ // Convert Turtle data to a stream
191
+ const textStream = $58194f7610fd9353$export$7b2e5d6b7377fcaf(turtleData);
192
+ // Use ParserN3 which outputs rdf-ext compatible quads directly
193
+ const parser = new (0, $85cNH$rdfjsparsern3)({
194
+ factory: (0, $85cNH$rdfext)
195
+ });
196
+ const quadStream = parser.import(textStream);
197
+ const dataset = await (0, $85cNH$rdfext).dataset().import(quadStream);
198
+ return dataset;
199
+ };
200
+
201
+
202
+ const $25cb6caf33e2f460$var$activitystreams = (0, $85cNH$jsonld1).activitystreams;
203
+ // Cache of SHACL validators
204
+ const $25cb6caf33e2f460$var$validatorCache = {};
205
+ /**
206
+ * Returns a SHACL validator for ActivityStreams shapes.
207
+ *
208
+ * This function creates a SHACL validator for ActivityStreams shapes using the
209
+ * `@activitypods/shape-definitions` package. It caches the validator to avoid
210
+ * creating it multiple times.
211
+ *
212
+ * @returns A Promise that resolves to a SHACL Validator instance.
213
+ */ const $25cb6caf33e2f460$export$8b707c2a07270e94 = async ()=>{
214
+ // Check if the validator is already cached
215
+ if ($25cb6caf33e2f460$var$validatorCache.activityStreams) return $25cb6caf33e2f460$var$validatorCache.activityStreams;
145
216
  try {
146
- // Add context to the JSON-LD object if needed
147
- const jsonLdWithContext = {
148
- ...jsonLdObj,
149
- '@context': context
150
- };
151
- // Convert JSON-LD object to string
152
- const jsonString = JSON.stringify(jsonLdWithContext);
153
- // Convert string to stream using the helper function
154
- const textStream = $25cb6caf33e2f460$var$stringToStream(jsonString);
155
- // Use the JsonLdParser that outputs rdf-ext compatible quads directly
156
- const parser = new (0, $85cNH$rdfjsparserjsonld)({
157
- factory: (0, $85cNH$rdfext)
217
+ const shapeDataset = await (0, $58194f7610fd9353$export$7304a15200aa09e5)($25cb6caf33e2f460$var$activitystreams);
218
+ // Create and cache the SHACL validator using the dataset
219
+ $25cb6caf33e2f460$var$validatorCache.activityStreams = new (0, $85cNH$Validator)(shapeDataset, {
220
+ factory: (0, $85cNH$rdfext),
221
+ debug: true
158
222
  });
159
- const quadStream = parser.import(textStream);
160
- // Collect quads into a dataset
161
- const dataset = (0, $85cNH$rdfext).dataset();
162
- for await (const quad of quadStream)dataset.add(quad);
163
- return dataset;
223
+ return $25cb6caf33e2f460$var$validatorCache.activityStreams;
164
224
  } catch (error) {
165
- console.error('Error parsing JSON-LD:', error);
166
- throw error;
225
+ throw new Error(`Failed to create ActivityStreams validator: ${error instanceof Error ? error.message : 'Unknown error'}`);
167
226
  }
227
+ const shapeDataset = await (0, $58194f7610fd9353$export$7304a15200aa09e5)($25cb6caf33e2f460$var$activitystreams);
228
+ // Create and cache the SHACL validator using the dataset
229
+ $25cb6caf33e2f460$var$validatorCache.activityStreams = new (0, $85cNH$Validator)(shapeDataset, {
230
+ factory: (0, $85cNH$rdfext),
231
+ debug: true
232
+ });
233
+ return $25cb6caf33e2f460$var$validatorCache.activitystreams;
168
234
  };
169
235
  // Helper function to load a SHACL shape and return a validator
170
236
  const $25cb6caf33e2f460$export$6de257db5bb9fd74 = async (shapeUri)=>{
171
237
  // Check if the validator is already cached
172
238
  if ($25cb6caf33e2f460$var$validatorCache[shapeUri]) return $25cb6caf33e2f460$var$validatorCache[shapeUri];
173
- const response = await fetch(shapeUri, {
174
- headers: {
175
- Accept: 'text/turtle'
176
- }
177
- });
178
- if (!response.ok) throw new Error(`Failed to load shape: ${response.status} ${response.statusText}`);
179
- // Get the Turtle data as text
180
- const turtleData = await response.text();
181
- // Convert text to stream using the helper function
182
- const textStream = $25cb6caf33e2f460$var$stringToStream(turtleData);
183
- // Use ParserN3 which outputs rdf-ext compatible quads directly
184
- const parser = new (0, $85cNH$rdfjsparsern3)({
185
- factory: (0, $85cNH$rdfext)
186
- });
187
- const quadStream = parser.import(textStream);
188
- // Collect quads into a dataset
189
- const shapeDataset = (0, $85cNH$rdfext).dataset();
190
- for await (const quad of quadStream)shapeDataset.add(quad);
191
- // Create and cache the SHACL validator using the dataset
192
- $25cb6caf33e2f460$var$validatorCache[shapeUri] = new (0, $85cNH$rdfvalidateshacl)(shapeDataset, {
193
- factory: (0, $85cNH$rdfext)
194
- });
195
- return $25cb6caf33e2f460$var$validatorCache[shapeUri];
239
+ try {
240
+ const response = await fetch(shapeUri, {
241
+ headers: {
242
+ Accept: 'text/turtle'
243
+ }
244
+ });
245
+ if (!response.ok) throw new Error(`Failed to load shape: ${response.status} ${response.statusText}`);
246
+ // Get the Turtle data as text
247
+ const turtleData = await response.text();
248
+ const shapeDataset = await (0, $58194f7610fd9353$export$7304a15200aa09e5)(turtleData);
249
+ // Create and cache the SHACL validator using the dataset
250
+ $25cb6caf33e2f460$var$validatorCache[shapeUri] = new (0, $85cNH$Validator)(shapeDataset, {
251
+ factory: (0, $85cNH$rdfext)
252
+ });
253
+ return $25cb6caf33e2f460$var$validatorCache[shapeUri];
254
+ } catch (error) {
255
+ throw new Error(`Failed to create SHACL validator for ${shapeUri}: ${error instanceof Error ? error.message : 'Unknown error'}`);
256
+ }
196
257
  };
197
- const $25cb6caf33e2f460$export$1558e55ae3912bbb = async (items, shaclValidator, context)=>{
258
+ /**
259
+ * Validates an array of items against a SHACL shape and returns the validation results.
260
+ *
261
+ * @param items The items to validate
262
+ * @param shaclValidator The SHACL validator to use
263
+ * @param context The context to use for the items
264
+ *
265
+ * @returns An array of objects containing the item and its validation result
266
+ */ const $25cb6caf33e2f460$export$1558e55ae3912bbb = async (items, shaclValidator, context)=>{
198
267
  if (!shaclValidator) throw new Error('validateItems: shaclValidator is required');
199
- if (!context) throw new Error('validateItems: context is required');
200
268
  return Promise.all(items.map(async (item)=>{
201
269
  try {
270
+ if (!item['@context']) item['@context'] = context;
202
271
  // Create a dataset from the item's JSON-LD
203
- const itemDataset = await $25cb6caf33e2f460$export$2684df65fa35e98e(item, context);
272
+ const itemDataset = await (0, $577f4953dfa5de4f$export$2684df65fa35e98e)(item);
204
273
  // Validate against the SHACL shape
205
- const report = shaclValidator?.validate(itemDataset);
274
+ const report = shaclValidator.validate({
275
+ dataset: itemDataset
276
+ });
206
277
  return {
207
278
  item: item,
208
- isValid: report?.conforms
279
+ isValid: report.conforms
209
280
  };
210
281
  } catch (error) {
211
- console.error(`Error validating item ${item.id}:`, error);
212
282
  return {
213
283
  item: item,
214
- isValid: false
284
+ isValid: false,
285
+ error: error
215
286
  };
216
287
  }
217
288
  }));
218
289
  };
290
+ /**
291
+ * Validates a subject against a set of SHACL shapes and returns the typed item if valid.
292
+ *
293
+ * @param subjectUri The subject to validate
294
+ * @param dataset The dataset containing the subject
295
+ * @param shapeTypes The shape types to validate against
296
+ * @param validator The SHACL validator to use
297
+ *
298
+ * @returns A typed item if valid, or null if not valid
299
+ */ const $25cb6caf33e2f460$export$c4cb1062f0ffb837 = async (subjectUri, dataset, shapeTypes, validator)=>{
300
+ const validationReport = await validator.validate(// Terms means the entry point from which should be validated, in our case the current item.
301
+ {
302
+ dataset: dataset,
303
+ terms: [
304
+ (0, $85cNH$rdfext).namedNode(subjectUri)
305
+ ]
306
+ }, // Here, terms means the shapes to validate against.
307
+ {
308
+ terms: shapeTypes.map((shapeType)=>(0, $85cNH$rdfext).namedNode(shapeType.shape))
309
+ });
310
+ if (!validationReport.conforms) return null;
311
+ const { results: results } = validationReport;
312
+ // Find the shape that matched the item in the report results.
313
+ const shapeType = shapeTypes.find((st)=>results.find((res)=>res.focusNode === subjectUri && res.shape === st.shape));
314
+ if (!shapeType) return null;
315
+ const typedItem = dataset.usingType(shapeType).fromSubject(subjectUri);
316
+ return typedItem;
317
+ };
219
318
 
220
319
 
221
320
  // Used to avoid re-renders
@@ -233,14 +332,17 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
233
332
  items
234
333
  ]);
235
334
  // Dereference all items, if necessary (even if shouldDereference is false, the hook needs to be called).
236
- const itemQueries = (0, $85cNH$useQueries)(!shouldDereference ? $8281f3ce3b9d6123$var$emptyArray : items.filter((item)=>typeof item === 'string').map((itemUri)=>({
237
- queryKey: [
238
- 'resource',
239
- itemUri
240
- ],
241
- queryFn: async ()=>(await dataProvider.fetch(itemUri)).json,
242
- staleTime: Infinity // Activities are immutable, so no need to refetch..
243
- })));
335
+ const itemQueries = (0, $85cNH$useQueries)({
336
+ queries: !shouldDereference ? $8281f3ce3b9d6123$var$emptyArray : items.filter((item)=>typeof item === 'string').map((itemUri)=>({
337
+ queryKey: [
338
+ 'resource',
339
+ itemUri
340
+ ],
341
+ queryFn: async ()=>(await dataProvider.fetch(itemUri)).json,
342
+ // TODO: Collections don't have to contain activities only, do they?
343
+ staleTime: Infinity // Activities are immutable, so no need to refetch..
344
+ }))
345
+ });
244
346
  if (!shouldDereference) return {
245
347
  loadedItems: items,
246
348
  isLoading: false,
@@ -259,7 +361,7 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
259
361
  };
260
362
  };
261
363
  /**
262
- * Subscribe a collection. Supports pagination.
364
+ * Subscribe toa collection. Supports pagination.
263
365
  * @param predicateOrUrl The collection URI or the predicate to get the collection URI from the identity (webId).
264
366
  * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false }`
265
367
  */ const $8281f3ce3b9d6123$var$useCollection = (predicateOrUrl, options = {})=>{
@@ -277,7 +379,7 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
277
379
  // Get collectionUrl from webId predicate or URL.
278
380
  const collectionUrl = (0, $85cNH$useMemo)(()=>{
279
381
  if (predicateOrUrl) {
280
- if (predicateOrUrl.startsWith('http')) return predicateOrUrl;
382
+ if (predicateOrUrl.startsWith('http') || predicateOrUrl.startsWith('did:ng:')) return predicateOrUrl;
281
383
  if (identity?.webIdData) return identity?.webIdData?.[predicateOrUrl];
282
384
  }
283
385
  return undefined;
@@ -295,10 +397,16 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
295
397
  let { json: json } = await dataProvider.fetch(nextPageUrl || collectionUrl);
296
398
  // If first page, handle this here.
297
399
  if ((json.type === 'OrderedCollection' || json.type === 'Collection') && json.first) {
298
- if (json.first?.items) {
299
- if (json.first?.items.length === 0 && json.first?.next) // Special case where the first property is an object without items
400
+ const firstItems = json.first?.items || json.first?.orderedItems;
401
+ if (firstItems) {
402
+ if (firstItems.length === 0 && json.first?.next) // Special case where the first property is an object without items
300
403
  ({ json: json } = await dataProvider.fetch(json.first?.next));
301
- else json = json.first;
404
+ else // Add the @context to the json, so that it can be used to expand the items
405
+ // That is necessary for the validation of the items
406
+ json = {
407
+ '@context': json['@context'],
408
+ ...json.first
409
+ };
302
410
  } else // Fetch the first page
303
411
  ({ json: json } = await dataProvider.fetch(json.first));
304
412
  }
@@ -320,6 +428,8 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
320
428
  // Validate the json with the SHACL shape
321
429
  if (shaclShapeUri !== '' && json[itemsKey] && json[itemsKey].length > 0) try {
322
430
  if (!json['@context']) throw new Error(`No context returned by the server.\nA context is required to expand the collection's items and validate them.`);
431
+ // TODO: Research: Is this used with the multi-purpose viewer already?
432
+ // How can multiple shapes be validated? Can we get this typed here?
323
433
  const shaclValidator = await (0, $25cb6caf33e2f460$export$6de257db5bb9fd74)(shaclShapeUri);
324
434
  const validatedResults = await (0, $25cb6caf33e2f460$export$1558e55ae3912bbb)((0, $577f4953dfa5de4f$export$e57ff0f701c44363)(json[itemsKey]), shaclValidator, json['@context']);
325
435
  // Keep only the valid item in the collection
@@ -338,16 +448,19 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
338
448
  shaclShapeUri
339
449
  ]);
340
450
  // Use infiniteQuery to handle pagination, fetching, etc.
341
- const { data: pageData, error: collectionError, fetchNextPage: fetchNextPage, refetch: refetch, hasNextPage: hasNextPage, isLoading: isLoadingPage, isFetching: isFetchingPage, isFetchingNextPage: isFetchingNextPage } = (0, $85cNH$useInfiniteQuery)([
342
- 'collection',
343
- {
344
- collectionUrl: collectionUrl,
345
- shaclShapeUri: shaclShapeUri
346
- }
347
- ], fetchCollection, {
451
+ const { data: pageData, error: collectionError, fetchNextPage: fetchNextPage, refetch: refetch, hasNextPage: hasNextPage, isLoading: isLoadingPage, isFetching: isFetchingPage, isFetchingNextPage: isFetchingNextPage } = (0, $85cNH$useInfiniteQuery)({
452
+ queryKey: [
453
+ 'collection',
454
+ {
455
+ collectionUrl: collectionUrl,
456
+ shaclShapeUri: shaclShapeUri
457
+ }
458
+ ],
348
459
  enabled: !!(collectionUrl && identity?.id),
460
+ initialPageParam: collectionUrl,
349
461
  getNextPageParam: (lastPage)=>lastPage.next,
350
- getPreviousPageParam: (firstPage)=>firstPage.prev
462
+ getPreviousPageParam: (firstPage)=>firstPage.prev,
463
+ queryFn: fetchCollection
351
464
  });
352
465
  // Put all items together in a list (and dereference, if required).
353
466
  const { loadedItems: items, isLoading: isLoadingItems, isFetching: isFetchingItems, errors: itemErrors } = $8281f3ce3b9d6123$var$useItemsFromPages(pageData?.pages ?? $8281f3ce3b9d6123$var$emptyArray, dereferenceItems);
@@ -377,13 +490,14 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
377
490
  oldData.pages = pages;
378
491
  return oldData;
379
492
  });
380
- if (shouldRefetch) setTimeout(()=>queryClient.refetchQueries([
381
- 'collection',
382
- {
383
- collectionUrl: collectionUrl
384
- }
385
- ], {
386
- active: true,
493
+ if (shouldRefetch) setTimeout(async ()=>queryClient.refetchQueries({
494
+ queryKey: [
495
+ 'collection',
496
+ {
497
+ collectionUrl: collectionUrl
498
+ }
499
+ ],
500
+ type: 'active',
387
501
  exact: true
388
502
  }), typeof shouldRefetch === 'number' ? shouldRefetch : 2000);
389
503
  }, [
@@ -415,13 +529,14 @@ const $8281f3ce3b9d6123$var$useItemsFromPages = (pages, dereferenceItems)=>{
415
529
  oldData.pages = pages;
416
530
  return oldData;
417
531
  });
418
- if (shouldRefetch) setTimeout(()=>queryClient.refetchQueries([
419
- 'collection',
420
- {
421
- collectionUrl: collectionUrl
422
- }
423
- ], {
424
- active: true,
532
+ if (shouldRefetch) setTimeout(()=>queryClient.refetchQueries({
533
+ queryKey: [
534
+ 'collection',
535
+ {
536
+ collectionUrl: collectionUrl
537
+ }
538
+ ],
539
+ type: 'active',
425
540
  exact: true
426
541
  }), typeof shouldRefetch === 'number' ? shouldRefetch : 2000);
427
542
  }, [
@@ -627,7 +742,7 @@ var $4d1d40fdbcd30589$export$2e2bcd8739ae039 = $4d1d40fdbcd30589$var$useOutbox;
627
742
  // Fix a bug in the current version of the mention extension
628
743
  // (The { id, label } object is located inside the id property)
629
744
  // See https://github.com/ueberdosis/tiptap/pull/1322
630
- const $6080c8a288f71367$var$CustomMention = (0, $85cNH$tiptapextensionmention).extend({
745
+ const $40f4c00d51a137ec$var$CustomMention = (0, $85cNH$tiptapextensionmention).extend({
631
746
  renderHTML ({ node: node, HTMLAttributes: HTMLAttributes }) {
632
747
  return [
633
748
  'span',
@@ -668,10 +783,10 @@ const $6080c8a288f71367$var$CustomMention = (0, $85cNH$tiptapextensionmention).e
668
783
  };
669
784
  }
670
785
  });
671
- var $6080c8a288f71367$export$2e2bcd8739ae039 = $6080c8a288f71367$var$CustomMention;
786
+ var $40f4c00d51a137ec$export$2e2bcd8739ae039 = $40f4c00d51a137ec$var$CustomMention;
672
787
 
673
788
 
674
- const $3c17312a40ebf1ed$var$useStyles = (0, $85cNH$muistylesmakeStyles)((theme)=>({
789
+ const $3047004939eff50c$var$useStyles = (0, $85cNH$makeStyles)()((theme)=>({
675
790
  form: {
676
791
  marginTop: -12 // Negative margin to keep the form close to the label
677
792
  },
@@ -717,12 +832,12 @@ const $3c17312a40ebf1ed$var$useStyles = (0, $85cNH$muistylesmakeStyles)((theme)=
717
832
  marginBottom: 15
718
833
  }
719
834
  }));
720
- const $3c17312a40ebf1ed$var$EmptyToolbar = ()=>null;
721
- const $3c17312a40ebf1ed$var$PostCommentForm = ({ context: context, placeholder: placeholder, helperText: helperText, mentions: mentions, userResource: userResource, addItem: addItem, removeItem: removeItem })=>{
835
+ const $3047004939eff50c$var$EmptyToolbar = ()=>null;
836
+ const $3047004939eff50c$var$PostCommentForm = ({ context: context, placeholder: placeholder, helperText: helperText, mentions: mentions, userResource: userResource, addItem: addItem, removeItem: removeItem })=>{
722
837
  const record = (0, $85cNH$useRecordContext)();
723
838
  const { data: identity, isLoading: isLoading } = (0, $85cNH$useGetIdentity)();
724
839
  const userDataModel = (0, $85cNH$useDataModel)(userResource);
725
- const classes = $3c17312a40ebf1ed$var$useStyles();
840
+ const { classes: classes } = $3047004939eff50c$var$useStyles();
726
841
  const notify = (0, $85cNH$useNotify)();
727
842
  const outbox = (0, $4d1d40fdbcd30589$export$2e2bcd8739ae039)();
728
843
  const [expanded, setExpanded] = (0, $85cNH$useState)(false);
@@ -732,11 +847,14 @@ const $3c17312a40ebf1ed$var$PostCommentForm = ({ context: context, placeholder:
732
847
  const mentions = Array.from(document.body.getElementsByClassName('mention'));
733
848
  const mentionedUsersUris = [];
734
849
  mentions.forEach((node)=>{
850
+ // @ts-expect-error TS(7015): Element implicitly has an 'any' type because index... Remove this comment to see the full error message
735
851
  const userUri = node.attributes['data-mention-id'].value;
852
+ // @ts-expect-error TS(7015): Element implicitly has an 'any' type because index... Remove this comment to see the full error message
736
853
  const userLabel = node.attributes['data-mention-label'].value;
737
854
  const link = document.createElement('a');
738
855
  link.setAttribute('href', `${new URL(window.location.href).origin}/${userResource}/${encodeURIComponent(userUri)}/show`);
739
856
  link.textContent = `@${userLabel}`;
857
+ // @ts-expect-error TS(2531): Object is possibly 'null'.
740
858
  node.parentNode.replaceChild(link, node);
741
859
  mentionedUsersUris.push(userUri);
742
860
  });
@@ -746,10 +864,10 @@ const $3c17312a40ebf1ed$var$PostCommentForm = ({ context: context, placeholder:
746
864
  else {
747
865
  const tempId = Date.now();
748
866
  const note = {
749
- type: (0, $338f387df48a40d7$export$c49cfb2681596b20).NOTE,
867
+ type: (0, $cb5f912aee8137fc$export$c49cfb2681596b20).NOTE,
750
868
  attributedTo: outbox.owner,
751
869
  content: document.body.innerHTML,
752
- inReplyTo: record[context],
870
+ inReplyTo: record?.[context],
753
871
  published: new Date().toISOString()
754
872
  };
755
873
  try {
@@ -763,7 +881,7 @@ const $3c17312a40ebf1ed$var$PostCommentForm = ({ context: context, placeholder:
763
881
  ...note,
764
882
  to: [
765
883
  ...mentionedUsersUris,
766
- (0, $338f387df48a40d7$export$4d8d554031975581)
884
+ (0, $cb5f912aee8137fc$export$4d8d554031975581)
767
885
  ]
768
886
  });
769
887
  notify("Commentaire post\xe9 avec succ\xe8s", {
@@ -802,13 +920,15 @@ const $3c17312a40ebf1ed$var$PostCommentForm = ({ context: context, placeholder:
802
920
  onClick: openAuthIfDisconnected,
803
921
  children: [
804
922
  /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$Avatar), {
805
- src: identity?.webIdData?.[userDataModel?.fieldsMapping?.image] || identity?.profileData?.[userDataModel?.fieldsMapping?.image],
923
+ src: // @ts-expect-error TS(2339): Property 'image' does not exist on type '{ title: ... Remove this comment to see the full error message
924
+ identity?.webIdData?.[userDataModel?.fieldsMapping?.image] || // @ts-expect-error TS(2339): Property 'image' does not exist on type '{ title: ... Remove this comment to see the full error message
925
+ identity?.profileData?.[userDataModel?.fieldsMapping?.image],
806
926
  className: classes.avatar
807
927
  }),
808
928
  /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$RichTextInput), {
809
929
  source: "comment",
810
930
  label: " ",
811
- toolbar: /*#__PURE__*/ (0, $85cNH$jsx)($3c17312a40ebf1ed$var$EmptyToolbar, {}),
931
+ toolbar: /*#__PURE__*/ (0, $85cNH$jsx)($3047004939eff50c$var$EmptyToolbar, {}),
812
932
  fullWidth: true,
813
933
  classes: {
814
934
  editorContent: classes.editorContent
@@ -819,11 +939,12 @@ const $3c17312a40ebf1ed$var$PostCommentForm = ({ context: context, placeholder:
819
939
  setExpanded(true);
820
940
  },
821
941
  extensions: [
942
+ // @ts-expect-error TS(2461): Type 'Extensions | undefined' is not an array type... Remove this comment to see the full error message
822
943
  ...(0, $85cNH$DefaultEditorOptions).extensions,
823
944
  placeholder ? (0, $85cNH$tiptapextensionplaceholder).configure({
824
945
  placeholder: placeholder
825
946
  }) : null,
826
- mentions ? (0, $6080c8a288f71367$export$2e2bcd8739ae039).configure({
947
+ mentions ? (0, $40f4c00d51a137ec$export$2e2bcd8739ae039).configure({
827
948
  HTMLAttributes: {
828
949
  class: 'mention'
829
950
  },
@@ -855,7 +976,7 @@ const $3c17312a40ebf1ed$var$PostCommentForm = ({ context: context, placeholder:
855
976
  ]
856
977
  });
857
978
  };
858
- var $3c17312a40ebf1ed$export$2e2bcd8739ae039 = $3c17312a40ebf1ed$var$PostCommentForm;
979
+ var $3047004939eff50c$export$2e2bcd8739ae039 = $3047004939eff50c$var$PostCommentForm;
859
980
 
860
981
 
861
982
 
@@ -865,7 +986,7 @@ var $3c17312a40ebf1ed$export$2e2bcd8739ae039 = $3c17312a40ebf1ed$var$PostComment
865
986
 
866
987
 
867
988
 
868
- const $be88b298220210d1$var$useStyles = (0, $85cNH$muistylesmakeStyles)(()=>({
989
+ const $74ea3002402ef672$var$useStyles = (0, $85cNH$makeStyles)()(()=>({
869
990
  container: {
870
991
  paddingLeft: 80,
871
992
  marginTop: 8,
@@ -909,13 +1030,13 @@ const $be88b298220210d1$var$useStyles = (0, $85cNH$muistylesmakeStyles)(()=>({
909
1030
  marginTop: 5
910
1031
  }
911
1032
  }));
912
- const $be88b298220210d1$var$CommentsList = ({ comments: comments, userResource: userResource, loading: loading })=>{
913
- const classes = $be88b298220210d1$var$useStyles();
1033
+ const $74ea3002402ef672$var$CommentsList = ({ comments: comments, userResource: userResource, loading: loading })=>{
1034
+ const { classes: classes } = $74ea3002402ef672$var$useStyles();
914
1035
  const userDataModel = (0, $85cNH$useDataModel)(userResource);
915
1036
  return /*#__PURE__*/ (0, $85cNH$jsxs)((0, $85cNH$Box), {
916
1037
  position: "relative",
917
1038
  children: [
918
- comments && comments.sort((a, b)=>new Date(b.published) - new Date(a.published)).map((comment)=>/*#__PURE__*/ (0, $85cNH$jsxs)((0, $85cNH$Box), {
1039
+ comments && comments.sort((a, b)=>new Date(b.published).getTime() - new Date(a.published).getTime()).map((comment)=>/*#__PURE__*/ (0, $85cNH$jsxs)((0, $85cNH$Box), {
919
1040
  className: classes.container,
920
1041
  children: [
921
1042
  /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$Box), {
@@ -943,7 +1064,7 @@ const $be88b298220210d1$var$CommentsList = ({ comments: comments, userResource:
943
1064
  linkType: "show",
944
1065
  children: /*#__PURE__*/ (0, $85cNH$jsx)((0, $85cNH$TextField), {
945
1066
  variant: "body2",
946
- source: userDataModel?.fieldsMapping?.title,
1067
+ source: userDataModel?.fieldsMapping?.title || '',
947
1068
  className: classes.label
948
1069
  })
949
1070
  }),
@@ -980,17 +1101,19 @@ const $be88b298220210d1$var$CommentsList = ({ comments: comments, userResource:
980
1101
  ]
981
1102
  });
982
1103
  };
983
- var $be88b298220210d1$export$2e2bcd8739ae039 = $be88b298220210d1$var$CommentsList;
1104
+ var $74ea3002402ef672$export$2e2bcd8739ae039 = $74ea3002402ef672$var$CommentsList;
984
1105
 
985
1106
 
986
1107
 
987
- const $7ce737d4a1c88e63$var$CommentsField = ({ source: source, context: context, helperText: helperText, placeholder: placeholder, userResource: userResource, mentions: mentions })=>{
1108
+ const $a8ae38fbe2f0ecc5$var$CommentsField = ({ source: source = 'id', context: context = 'id', helperText: helperText, placeholder: placeholder = "Commencez \xe0 taper votre commentaire...", userResource: userResource, mentions: mentions })=>{
988
1109
  const record = (0, $85cNH$useRecordContext)();
989
- const { items: comments, loading: loading, addItem: addItem, removeItem: removeItem } = (0, $8281f3ce3b9d6123$export$2e2bcd8739ae039)(record.replies);
1110
+ const { items: comments, isLoading: isLoading, addItem: addItem, removeItem: removeItem } = (0, $8281f3ce3b9d6123$export$2e2bcd8739ae039)(record?.replies, {
1111
+ liveUpdates: true
1112
+ });
990
1113
  if (!userResource) throw new Error('No userResource defined for CommentsField');
991
1114
  return /*#__PURE__*/ (0, $85cNH$jsxs)((0, $85cNH$Fragment), {
992
1115
  children: [
993
- /*#__PURE__*/ (0, $85cNH$jsx)((0, $3c17312a40ebf1ed$export$2e2bcd8739ae039), {
1116
+ /*#__PURE__*/ (0, $85cNH$jsx)((0, $3047004939eff50c$export$2e2bcd8739ae039), {
994
1117
  context: context,
995
1118
  helperText: helperText,
996
1119
  userResource: userResource,
@@ -999,28 +1122,22 @@ const $7ce737d4a1c88e63$var$CommentsField = ({ source: source, context: context,
999
1122
  addItem: addItem,
1000
1123
  removeItem: removeItem
1001
1124
  }),
1002
- /*#__PURE__*/ (0, $85cNH$jsx)((0, $be88b298220210d1$export$2e2bcd8739ae039), {
1125
+ /*#__PURE__*/ (0, $85cNH$jsx)((0, $74ea3002402ef672$export$2e2bcd8739ae039), {
1003
1126
  comments: comments,
1004
- loading: loading,
1127
+ loading: isLoading,
1005
1128
  userResource: userResource
1006
1129
  })
1007
1130
  ]
1008
1131
  });
1009
1132
  };
1010
- $7ce737d4a1c88e63$var$CommentsField.defaultProps = {
1011
- label: 'Commentaires',
1012
- placeholder: "Commencez \xe0 taper votre commentaire...",
1013
- source: 'id',
1014
- context: 'id'
1015
- };
1016
- var $7ce737d4a1c88e63$export$2e2bcd8739ae039 = $7ce737d4a1c88e63$var$CommentsField;
1133
+ var $a8ae38fbe2f0ecc5$export$2e2bcd8739ae039 = $a8ae38fbe2f0ecc5$var$CommentsField;
1017
1134
 
1018
1135
 
1019
1136
 
1020
1137
 
1021
1138
 
1022
1139
 
1023
- const $d3be168cd1e7aaae$var$CollectionList = ({ collectionUrl: collectionUrl, resource: resource, children: children })=>{
1140
+ const $f2bfc37210e303cc$var$CollectionList = ({ collectionUrl: collectionUrl, resource: resource, children: children })=>{
1024
1141
  if ((0, $85cNH$react).Children.count(children) !== 1) throw new Error('<CollectionList> only accepts a single child');
1025
1142
  const { items: actorsUris } = (0, $8281f3ce3b9d6123$export$2e2bcd8739ae039)(collectionUrl);
1026
1143
  const { data: data, isLoading: isLoading, isFetching: isFetching } = (0, $85cNH$useGetMany)(resource, {
@@ -1040,31 +1157,302 @@ const $d3be168cd1e7aaae$var$CollectionList = ({ collectionUrl: collectionUrl, re
1040
1157
  children: children
1041
1158
  });
1042
1159
  };
1043
- var $d3be168cd1e7aaae$export$2e2bcd8739ae039 = $d3be168cd1e7aaae$var$CollectionList;
1160
+ var $f2bfc37210e303cc$export$2e2bcd8739ae039 = $f2bfc37210e303cc$var$CollectionList;
1044
1161
 
1045
1162
 
1046
1163
 
1047
1164
 
1048
1165
 
1049
1166
 
1050
- const $ea214512ab1a2e8f$var$ReferenceCollectionField = ({ source: source, reference: reference, children: children, ...rest })=>{
1167
+ const $4d1eaed181ef6aa8$var$ReferenceCollectionField = ({ source: source, reference: reference, children: children, ...rest })=>{
1051
1168
  const record = (0, $85cNH$useRecordContext)();
1052
1169
  if ((0, $85cNH$react).Children.count(children) !== 1) throw new Error('<ReferenceCollectionField> only accepts a single child');
1053
1170
  if (!record || !record[source]) return null;
1054
- return /*#__PURE__*/ (0, $85cNH$jsx)((0, $d3be168cd1e7aaae$export$2e2bcd8739ae039), {
1171
+ return /*#__PURE__*/ (0, $85cNH$jsx)((0, $f2bfc37210e303cc$export$2e2bcd8739ae039), {
1055
1172
  resource: reference,
1056
1173
  collectionUrl: record[source],
1057
1174
  ...rest,
1058
1175
  children: children
1059
1176
  });
1060
1177
  };
1061
- var $ea214512ab1a2e8f$export$2e2bcd8739ae039 = $ea214512ab1a2e8f$var$ReferenceCollectionField;
1178
+ var $4d1eaed181ef6aa8$export$2e2bcd8739ae039 = $4d1eaed181ef6aa8$var$ReferenceCollectionField;
1179
+
1180
+
1062
1181
 
1063
1182
 
1064
1183
 
1065
1184
 
1066
1185
 
1067
1186
 
1187
+
1188
+
1189
+
1190
+
1191
+
1192
+ /**
1193
+ * Subscribe to a collection. Supports pagination.
1194
+ * @param collectionUri The collection URI or the predicate to get the collection URI from the identity (webId).
1195
+ * @param {UseCollectionOptions & UseTypedCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false, pageSize: 10 }` and requires at least one ldo @see {ShapeType}.
1196
+ */ const $75609b4dfb738328$var$useTypedCollection = (collectionUri, options)=>{
1197
+ const { pageSize: pageSize = 10, liveUpdates: subscribeToUpdates = false, shapeTypes: shapeTypes } = options;
1198
+ if (!shapeTypes.length) throw new Error('At least one ShapeType is required to filter the collection by.');
1199
+ // 1. Fetch the collection
1200
+ const collectionQuery = $75609b4dfb738328$var$useInfiniteCollectionQuery(collectionUri);
1201
+ const { totalItems: totalItems, isPaginated: isPaginated } = $75609b4dfb738328$var$useTotalItemsFromPages(collectionQuery.data);
1202
+ // 2. Filter items from the collection pages that match the given shape types.
1203
+ const filteredItems = $75609b4dfb738328$var$useFilteredItemsFromPages(collectionQuery.data, shapeTypes);
1204
+ // 3. Set up notifications for live updates, if enabled.
1205
+ const liveUpdatesStatus = $75609b4dfb738328$var$useSubscribeToUpdates({
1206
+ uri: collectionUri,
1207
+ enabled: subscribeToUpdates,
1208
+ onAddItem: (_item)=>{
1209
+ // Since we don't know where the item was added, we refetch the whole collection ¯\_(ツ)_/¯.
1210
+ collectionQuery.refetch();
1211
+ },
1212
+ onRemoveItem: (uri)=>{
1213
+ $75609b4dfb738328$var$removeItemFromQueryData(uri, collectionQuery);
1214
+ }
1215
+ });
1216
+ // 4. Pagination logic.
1217
+ const [requestedNextItems, setRequestedNextItems] = (0, $85cNH$useState)(pageSize);
1218
+ const [requestedPrevItems, setRequestedPrevItems] = (0, $85cNH$useState)(0);
1219
+ // Automatically fetch next page, if more items are requested.
1220
+ (0, $85cNH$useEffect)(()=>{
1221
+ if (requestedNextItems > filteredItems.length && collectionQuery.hasNextPage && !collectionQuery.isLoading) collectionQuery.fetchNextPage();
1222
+ }, [
1223
+ requestedNextItems,
1224
+ filteredItems.length,
1225
+ collectionQuery.hasNextPage,
1226
+ collectionQuery.isLoading
1227
+ ]);
1228
+ // Automatically fetch previous page, if more items are requested.
1229
+ (0, $85cNH$useEffect)(()=>{
1230
+ if (requestedPrevItems > filteredItems.length && collectionQuery.hasPreviousPage && !collectionQuery.isLoading) collectionQuery.fetchPreviousPage();
1231
+ }, [
1232
+ requestedPrevItems,
1233
+ filteredItems.length,
1234
+ collectionQuery.hasPreviousPage,
1235
+ collectionQuery.isLoading
1236
+ ]);
1237
+ /** Fetch next n (filtered) items. */ const fetchNext = (0, $85cNH$useCallback)((noItems = pageSize)=>{
1238
+ setRequestedNextItems(filteredItems.length + noItems);
1239
+ }, [
1240
+ filteredItems.length,
1241
+ pageSize
1242
+ ]);
1243
+ /** Fetch previous n (filtered) items. */ const fetchPrevious = (0, $85cNH$useCallback)((noItems = pageSize)=>{
1244
+ setRequestedPrevItems(filteredItems.length + noItems);
1245
+ }, [
1246
+ filteredItems.length,
1247
+ pageSize
1248
+ ]);
1249
+ return {
1250
+ // TODO: Do we want to expose all properties from the collection query?
1251
+ ...collectionQuery,
1252
+ items: filteredItems,
1253
+ liveUpdatesStatus: liveUpdatesStatus,
1254
+ fetchNext: fetchNext,
1255
+ fetchPrevious: fetchPrevious,
1256
+ totalItems: totalItems,
1257
+ isPaginated: isPaginated
1258
+ };
1259
+ };
1260
+ var $75609b4dfb738328$export$2e2bcd8739ae039 = $75609b4dfb738328$var$useTypedCollection;
1261
+ const $75609b4dfb738328$var$useSubscribeToUpdates = ({ uri: uri, enabled: enabled = true, onAddItem: onAddItem, onRemoveItem: onRemoveItem })=>{
1262
+ const { fetch: fetchFn } = (0, $85cNH$useDataProvider)();
1263
+ const [status, setStatus] = (0, $85cNH$useState)({
1264
+ status: enabled ? 'connecting' : 'disabled'
1265
+ });
1266
+ (0, $85cNH$useEffect)(()=>{
1267
+ const webSocketRef = (0, $85cNH$useRef)(null);
1268
+ // Nothing to do, return empty clean up function.
1269
+ if (!enabled || !uri) return ()=>{};
1270
+ // Create ws that listens to collectionUri changes
1271
+ (0, $85cNH$getOrCreateWsChannel)(fetchFn, uri).then((ws)=>{
1272
+ webSocketRef.current = ws; // Keep a ref to the webSocket so that it can be used elsewhere
1273
+ webSocketRef.current.addEventListener('message', (event)=>{
1274
+ // TODO: correct ldo type
1275
+ const data = JSON.parse(event.data);
1276
+ if (data.type === 'Add') onAddItem(data.object);
1277
+ else if (data.type === 'Remove') onRemoveItem(data.object);
1278
+ });
1279
+ webSocketRef.current.addEventListener('error', (event)=>{
1280
+ setStatus({
1281
+ error: event,
1282
+ status: 'error'
1283
+ });
1284
+ // TODO: Retry after a while (use react query?).
1285
+ });
1286
+ webSocketRef.current.addEventListener('close', (_event)=>{
1287
+ if (!status.error) setStatus({
1288
+ status: 'closed'
1289
+ });
1290
+ });
1291
+ }).catch((error)=>{
1292
+ setStatus({
1293
+ status: 'error',
1294
+ error: error
1295
+ });
1296
+ });
1297
+ // Clean up, i.e. close channel.
1298
+ return ()=>{
1299
+ webSocketRef.current?.close();
1300
+ };
1301
+ }, [
1302
+ uri,
1303
+ enabled,
1304
+ onAddItem,
1305
+ onRemoveItem
1306
+ ]);
1307
+ return status;
1308
+ };
1309
+ const $75609b4dfb738328$var$useInfiniteCollectionQuery = (collectionUri)=>{
1310
+ const { data: identity } = (0, $85cNH$useGetIdentity)();
1311
+ const dataProvider = (0, $85cNH$useDataProvider)();
1312
+ const { fetch: fetchFn } = dataProvider;
1313
+ const infiniteQueryData = (0, $85cNH$useInfiniteQuery)({
1314
+ queryKey: [
1315
+ 'collection',
1316
+ {
1317
+ uri: collectionUri
1318
+ }
1319
+ ],
1320
+ queryFn: $75609b4dfb738328$var$getFetchCollectionPage(fetchFn),
1321
+ initialPageParam: collectionUri,
1322
+ enabled: !!(collectionUri && identity?.id),
1323
+ getNextPageParam: (current)=>current.data?.next,
1324
+ getPreviousPageParam: (current)=>current.data?.prev
1325
+ });
1326
+ return infiniteQueryData;
1327
+ };
1328
+ const $75609b4dfb738328$var$getFetchCollectionPage = (fetchFn)=>async ({ pageParam: pageUri })=>{
1329
+ // Note, page is not necessarily of type OrderedCollectionPage but it is a partial in any case.
1330
+ const jsonPage = await (await fetchFn(pageUri)).json();
1331
+ if (!jsonPage || typeof jsonPage !== 'object') throw new Error(`Could not fetch page ${pageUri}. Response is invalid.`);
1332
+ const itemsKey = 'orderedItems' in jsonPage ? 'orderedItems' : 'items';
1333
+ if ((0, $577f4953dfa5de4f$export$e57ff0f701c44363)(jsonPage[itemsKey]).length === 0) // No items in page.
1334
+ return {
1335
+ itemIds: [],
1336
+ dataset: null,
1337
+ data: null
1338
+ };
1339
+ // Keep track of item ids in this order (in the rdf dataset the order is lost).
1340
+ const itemIds = (0, $577f4953dfa5de4f$export$e57ff0f701c44363)(jsonPage[itemsKey]).map((itemOrId)=>itemOrId?.['@id'] || itemOrId?.id || itemOrId).filter((item)=>item); // Ensure item is not undefined.
1341
+ // Parse the page into a dataset.
1342
+ // TODO: Move to data provider.
1343
+ const dataset = (0, $85cNH$createConnectedLdoDataset)([
1344
+ (0, $85cNH$solidConnectedPlugin)
1345
+ ]);
1346
+ dataset.setContext('solid', {
1347
+ fetch: fetchFn
1348
+ });
1349
+ dataset.addAll(await (0, $577f4953dfa5de4f$export$7089f01fea2fc5c2)(jsonPage));
1350
+ const resource = dataset.getResource(pageUri);
1351
+ if (resource.type === 'InvalidIdentifierResource') return {
1352
+ itemIds: itemIds,
1353
+ dataset: null,
1354
+ pageUri: pageUri,
1355
+ data: null
1356
+ };
1357
+ const ldoBuilder = dataset.usingType((0, $85cNH$OrderedCollectionPageShapeType));
1358
+ // Run a link query to ensure that all items are dereferenced (the results are kept in the dataset).
1359
+ await ldoBuilder.startLinkQuery(resource, pageUri, {
1360
+ items: true,
1361
+ orderedItems: true
1362
+ }).run({
1363
+ reload: false
1364
+ });
1365
+ return {
1366
+ dataset: dataset,
1367
+ itemIds: itemIds,
1368
+ pageUri: pageUri,
1369
+ data: ldoBuilder.fromSubject(pageUri)
1370
+ };
1371
+ };
1372
+ const $75609b4dfb738328$var$useTotalItemsFromPages = (queryData)=>{
1373
+ if (!queryData?.pages.length) return {
1374
+ isPaginated: undefined,
1375
+ totalItems: undefined
1376
+ };
1377
+ const { pages: pages } = queryData;
1378
+ // Check if collection is paginated. We assume that the collection is paginated if there are pages with first, last, prev or next.
1379
+ const isPaginated = pages.length === 0 ? undefined : !!pages.find((page)=>page.data && ('first' in page.data || 'next' in page.data || 'last' in page.data || 'prev' in page.data));
1380
+ // Approach 1: Get total items info by checking if the page has a totalItems property.
1381
+ const totalItemsByCollectionInfo = pages.find((page)=>'totalItems' in page)?.data?.totalItems;
1382
+ if (totalItemsByCollectionInfo) return {
1383
+ totalItems: totalItemsByCollectionInfo,
1384
+ isPaginated: isPaginated
1385
+ };
1386
+ // Approach 2: If collection is not paginated, we count the number of items in the collection.
1387
+ if (!isPaginated) return {
1388
+ totalItems: pages[0].itemIds.length,
1389
+ isPaginated: isPaginated
1390
+ };
1391
+ // Approach 3: If we have the whole collection loaded, we can count the items.
1392
+ const firstPage = pages.find((page)=>page.data?.first)?.data?.first;
1393
+ const lastPage = pages.find((page)=>page.data?.last)?.data?.last;
1394
+ // We assume that all pages are loaded if the first and last page is available.
1395
+ // In that case, count all pages' items.
1396
+ if (firstPage && lastPage) return {
1397
+ isPaginated: isPaginated,
1398
+ totalItems: pages// Get length of page
1399
+ .map((page)=>page.data?.orderedItems?.size || page.data?.items?.size || 0)// Sum all page length counts.
1400
+ .reduce((prev, current)=>prev + current)
1401
+ };
1402
+ // If no approach succeeded, we return undefined.
1403
+ return {
1404
+ totalItems: undefined,
1405
+ isPaginated: isPaginated
1406
+ };
1407
+ };
1408
+ const $75609b4dfb738328$var$useFilteredItemsFromPages = (queryData, shapeTypes)=>{
1409
+ const [filteredItems, setFilteredItems] = (0, $85cNH$useState)([]);
1410
+ const filterItems = (0, $85cNH$useCallback)(async ()=>{
1411
+ // We need to load the shacl resources and match them to the shape types.
1412
+ const validator = await (0, $25cb6caf33e2f460$export$8b707c2a07270e94)();
1413
+ const pages = queryData?.pages;
1414
+ if (!pages || pages.length === 0) {
1415
+ setFilteredItems([]);
1416
+ return;
1417
+ }
1418
+ const validatedItems = await Promise.all(// For every page, ...
1419
+ queryData.pages.map(async (page)=>{
1420
+ const items = await Promise.all(// For every item in the page, ...
1421
+ page.itemIds.map(async (itemId)=>// Validate item against the shape types and return the ldo object of the correct type, if it is valid.
1422
+ page.dataset && (0, $25cb6caf33e2f460$export$c4cb1062f0ffb837)(itemId, page.dataset, shapeTypes, validator))).then((results)=>results.filter((item)=>!!item)); // Filter out null items.
1423
+ return items;
1424
+ })).then((results)=>results.flat());
1425
+ // TODO: Order items by ids.
1426
+ setFilteredItems(validatedItems);
1427
+ // TODO: Cache filtered items by page, so that we don't have to re-filter them every time?
1428
+ }, [
1429
+ queryData?.pages,
1430
+ shapeTypes
1431
+ ]);
1432
+ (0, $85cNH$useEffect)(()=>{
1433
+ filterItems();
1434
+ }, [
1435
+ filterItems
1436
+ ]);
1437
+ return filteredItems;
1438
+ };
1439
+ /** A somewhat hacky way to remove an item from the useInfiniteCollectionQuery. */ const $75609b4dfb738328$var$removeItemFromQueryData = (itemUri, collectionQuery)=>{
1440
+ // Manipulate data about total items. Sorry, a bit hacky...
1441
+ collectionQuery.data?.pages.forEach((page)=>{
1442
+ if (!page.dataset) return;
1443
+ page.dataset.deleteMatches((0, $85cNH$rdfext).namedNode(itemUri));
1444
+ // There might be a totalItems property in the page, so we need to update it.
1445
+ if (page.data.totalItems && Number.isInteger(page.data.totalItems)) // eslint-disable-next-line no-param-reassign
1446
+ page.data.totalItems -= 1;
1447
+ });
1448
+ }; // Open Question:
1449
+ // - Use one dataset? It has the benefit of only having to define a single solid connected dataset and makes ng switching easier -> no need to create a connected dataset.
1450
+ // - On the other hand (the only downside I can think of rn): Either you have to remove expired items from the dataset or you don't care about old data that is not used by react admin anymore. At a refetch all old data would have to be removed though.
1451
+
1452
+
1453
+
1454
+
1455
+
1068
1456
  /**
1069
1457
  * Hook to fetch the inbox of the logged user.
1070
1458
  * Returns the same data as the useCollection hooks, plus:
@@ -1123,7 +1511,7 @@ var $6a227ddc2fd92a7a$export$2e2bcd8739ae039 = $6a227ddc2fd92a7a$var$useNodeinfo
1123
1511
 
1124
1512
 
1125
1513
 
1126
- const $2514c63dc8f4867c$var$useWebfinger = ()=>{
1514
+ const $d33ef82068985aa5$var$useWebfinger = ()=>{
1127
1515
  // Post an activity to the logged user's outbox and return its URI
1128
1516
  const fetch = (0, $85cNH$useCallback)(async (id)=>{
1129
1517
  // eslint-disable-next-line
@@ -1144,7 +1532,7 @@ const $2514c63dc8f4867c$var$useWebfinger = ()=>{
1144
1532
  fetch: fetch
1145
1533
  };
1146
1534
  };
1147
- var $2514c63dc8f4867c$export$2e2bcd8739ae039 = $2514c63dc8f4867c$var$useWebfinger;
1535
+ var $d33ef82068985aa5$export$2e2bcd8739ae039 = $d33ef82068985aa5$var$useWebfinger;
1148
1536
 
1149
1537
 
1150
1538
 
@@ -1155,7 +1543,7 @@ var $2514c63dc8f4867c$export$2e2bcd8739ae039 = $2514c63dc8f4867c$var$useWebfinge
1155
1543
 
1156
1544
 
1157
1545
 
1158
- const $cebd295d444aa91c$var$useStyles = (0, $85cNH$muistylesmakeStyles)((theme)=>({
1546
+ const $2d6cf763aa4118ce$var$useStyles = (0, $85cNH$makeStyles)()((theme)=>({
1159
1547
  items: {
1160
1548
  background: '#fff',
1161
1549
  borderRadius: '0.5rem',
@@ -1180,24 +1568,29 @@ const $cebd295d444aa91c$var$useStyles = (0, $85cNH$muistylesmakeStyles)((theme)=
1180
1568
  }
1181
1569
  }
1182
1570
  }));
1183
- var $cebd295d444aa91c$export$2e2bcd8739ae039 = /*#__PURE__*/ (0, $85cNH$forwardRef)((props, ref)=>{
1571
+ var $2d6cf763aa4118ce$export$2e2bcd8739ae039 = /*#__PURE__*/ (0, $85cNH$forwardRef)((props, ref)=>{
1184
1572
  const [selectedIndex, setSelectedIndex] = (0, $85cNH$useState)(0);
1185
- const classes = $cebd295d444aa91c$var$useStyles();
1573
+ const { classes: classes } = $2d6cf763aa4118ce$var$useStyles();
1186
1574
  const selectItem = (index)=>{
1575
+ // @ts-expect-error TS(2339): Property 'items' does not exist on type '{}'.
1187
1576
  const item = props.items[index];
1188
- if (item) props.command({
1577
+ if (item) // @ts-expect-error TS(2339): Property 'command' does not exist on type '{}'.
1578
+ props.command({
1189
1579
  id: item
1190
1580
  });
1191
1581
  };
1192
1582
  const upHandler = ()=>{
1583
+ // @ts-expect-error TS(2339): Property 'items' does not exist on type '{}'.
1193
1584
  setSelectedIndex((selectedIndex + props.items.length - 1) % props.items.length);
1194
1585
  };
1195
1586
  const downHandler = ()=>{
1587
+ // @ts-expect-error TS(2339): Property 'items' does not exist on type '{}'.
1196
1588
  setSelectedIndex((selectedIndex + 1) % props.items.length);
1197
1589
  };
1198
1590
  const enterHandler = ()=>{
1199
1591
  selectItem(selectedIndex);
1200
1592
  };
1593
+ // @ts-expect-error TS(2339): Property 'items' does not exist on type '{}'.
1201
1594
  (0, $85cNH$useEffect)(()=>setSelectedIndex(0), [
1202
1595
  props.items
1203
1596
  ]);
@@ -1220,7 +1613,8 @@ var $cebd295d444aa91c$export$2e2bcd8739ae039 = /*#__PURE__*/ (0, $85cNH$forwardR
1220
1613
  }));
1221
1614
  return /*#__PURE__*/ (0, $85cNH$jsx)("div", {
1222
1615
  className: classes.items,
1223
- children: props.items.length ? props.items.map((item, index)=>/*#__PURE__*/ (0, $85cNH$jsx)("button", {
1616
+ children: props.items.length ? // @ts-expect-error TS(2339): Property 'items' does not exist on type '{}'.
1617
+ props.items.map((item, index)=>/*#__PURE__*/ (0, $85cNH$jsx)("button", {
1224
1618
  className: classes.item + (index === selectedIndex ? ' selected' : ''),
1225
1619
  onClick: ()=>selectItem(index),
1226
1620
  children: item.label
@@ -1232,12 +1626,12 @@ var $cebd295d444aa91c$export$2e2bcd8739ae039 = /*#__PURE__*/ (0, $85cNH$forwardR
1232
1626
  });
1233
1627
 
1234
1628
 
1235
- const $a2389704c0801b9a$var$renderMentions = ()=>{
1629
+ const $81b58d0f1db1e46b$var$renderMentions = ()=>{
1236
1630
  let component;
1237
1631
  let popup;
1238
1632
  return {
1239
1633
  onStart: (props)=>{
1240
- component = new (0, $85cNH$ReactRenderer)((0, $cebd295d444aa91c$export$2e2bcd8739ae039), {
1634
+ component = new (0, $85cNH$ReactRenderer)((0, $2d6cf763aa4118ce$export$2e2bcd8739ae039), {
1241
1635
  props: props,
1242
1636
  editor: props.editor
1243
1637
  });
@@ -1270,10 +1664,10 @@ const $a2389704c0801b9a$var$renderMentions = ()=>{
1270
1664
  }
1271
1665
  };
1272
1666
  };
1273
- var $a2389704c0801b9a$export$2e2bcd8739ae039 = $a2389704c0801b9a$var$renderMentions;
1667
+ var $81b58d0f1db1e46b$export$2e2bcd8739ae039 = $81b58d0f1db1e46b$var$renderMentions;
1274
1668
 
1275
1669
 
1276
- const $51cccd331ea8b13d$var$useMentions = (userResource)=>{
1670
+ const $2444c190214b72ec$var$useMentions = (userResource)=>{
1277
1671
  const userDataModel = (0, $85cNH$useDataModel)(userResource);
1278
1672
  const { data: data } = (0, $85cNH$useGetList)(userResource, {
1279
1673
  filter: {
@@ -1288,7 +1682,7 @@ const $51cccd331ea8b13d$var$useMentions = (userResource)=>{
1288
1682
  const availableMentions = (0, $85cNH$useMemo)(()=>{
1289
1683
  if (data) return data.map((item)=>({
1290
1684
  id: item.id,
1291
- label: item[userDataModel?.fieldsMapping?.title]
1685
+ label: item[userDataModel?.fieldsMapping?.title || '']
1292
1686
  }));
1293
1687
  }, [
1294
1688
  data
@@ -1302,14 +1696,14 @@ const $51cccd331ea8b13d$var$useMentions = (userResource)=>{
1302
1696
  ]);
1303
1697
  return {
1304
1698
  items: items,
1305
- render: (0, $a2389704c0801b9a$export$2e2bcd8739ae039)
1699
+ render: (0, $81b58d0f1db1e46b$export$2e2bcd8739ae039)
1306
1700
  };
1307
1701
  };
1308
- var $51cccd331ea8b13d$export$2e2bcd8739ae039 = $51cccd331ea8b13d$var$useMentions;
1702
+ var $2444c190214b72ec$export$2e2bcd8739ae039 = $2444c190214b72ec$var$useMentions;
1309
1703
 
1310
1704
 
1311
1705
 
1312
1706
 
1313
1707
 
1314
- 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};
1708
+ export {$a8ae38fbe2f0ecc5$export$2e2bcd8739ae039 as CommentsField, $f2bfc37210e303cc$export$2e2bcd8739ae039 as CollectionList, $4d1eaed181ef6aa8$export$2e2bcd8739ae039 as ReferenceCollectionField, $8281f3ce3b9d6123$export$2e2bcd8739ae039 as useCollection, $75609b4dfb738328$export$2e2bcd8739ae039 as useTypedCollection, $cc1d1cd0e97c63a2$export$2e2bcd8739ae039 as useInbox, $6a227ddc2fd92a7a$export$2e2bcd8739ae039 as useNodeinfo, $4d1d40fdbcd30589$export$2e2bcd8739ae039 as useOutbox, $d33ef82068985aa5$export$2e2bcd8739ae039 as useWebfinger, $2444c190214b72ec$export$2e2bcd8739ae039 as useMentions, $cb5f912aee8137fc$export$1ec8e53e7d982d22 as ACTIVITY_TYPES, $cb5f912aee8137fc$export$9649665d7ccb0dc2 as ACTOR_TYPES, $cb5f912aee8137fc$export$c49cfb2681596b20 as OBJECT_TYPES, $cb5f912aee8137fc$export$4d8d554031975581 as PUBLIC_URI};
1315
1709
  //# sourceMappingURL=index.es.js.map