@semapps/activitypub-components 1.1.4 → 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.cjs.js CHANGED
@@ -4,19 +4,24 @@ var $583VT$reactadmin = require("react-admin");
4
4
  var $583VT$rainputrichtext = require("ra-input-rich-text");
5
5
  var $583VT$tiptapextensionplaceholder = require("@tiptap/extension-placeholder");
6
6
  var $583VT$muimaterial = require("@mui/material");
7
- var $583VT$muistylesmakeStyles = require("@mui/styles/makeStyles");
7
+ var $583VT$tssreactmui = require("tss-react/mui");
8
8
  var $583VT$muiiconsmaterialSend = require("@mui/icons-material/Send");
9
9
  var $583VT$semappssemanticdataprovider = require("@semapps/semantic-data-provider");
10
10
  var $583VT$semappsauthprovider = require("@semapps/auth-provider");
11
- var $583VT$reactquery = require("react-query");
12
- var $583VT$rdfvalidateshacl = require("rdf-validate-shacl");
11
+ var $583VT$tanstackreactquery = require("@tanstack/react-query");
12
+ var $583VT$jsonld = require("jsonld");
13
13
  var $583VT$rdfext = require("rdf-ext");
14
- var $583VT$rdfjsparserjsonld = require("@rdfjs/parser-jsonld");
15
- var $583VT$readablewebtonodestream = require("readable-web-to-node-stream");
16
14
  var $583VT$rdfjsparsern3 = require("@rdfjs/parser-n3");
15
+ var $583VT$readablestream = require("readable-stream");
16
+ var $583VT$shaclengine = require("shacl-engine");
17
+ var $583VT$activitypodsshapedefinitions = require("@activitypods/shape-definitions");
18
+ var $583VT$readablewebtonodestream = require("readable-web-to-node-stream");
17
19
  var $583VT$tiptapcore = require("@tiptap/core");
18
20
  var $583VT$tiptapextensionmention = require("@tiptap/extension-mention");
19
21
  var $583VT$semappsfieldcomponents = require("@semapps/field-components");
22
+ var $583VT$ldoconnected = require("@ldo/connected");
23
+ var $583VT$ldoconnectedsolid = require("@ldo/connected-solid");
24
+ var $583VT$activitypodsldoshapes = require("@activitypods/ldo-shapes");
20
25
  var $583VT$tiptapreact = require("@tiptap/react");
21
26
  var $583VT$tippyjs = require("tippy.js");
22
27
 
@@ -29,19 +34,20 @@ function $parcel$interopDefault(a) {
29
34
  return a && a.__esModule ? a.default : a;
30
35
  }
31
36
 
32
- $parcel$export(module.exports, "CommentsField", () => $2e5504cc4159ca8d$export$2e2bcd8739ae039);
33
- $parcel$export(module.exports, "CollectionList", () => $505d598a33288aad$export$2e2bcd8739ae039);
34
- $parcel$export(module.exports, "ReferenceCollectionField", () => $b0c94a9bdea99da5$export$2e2bcd8739ae039);
37
+ $parcel$export(module.exports, "CommentsField", () => $484cf98a20a766f7$export$2e2bcd8739ae039);
38
+ $parcel$export(module.exports, "CollectionList", () => $78e7af8b8abfe6a7$export$2e2bcd8739ae039);
39
+ $parcel$export(module.exports, "ReferenceCollectionField", () => $63048bed1787ac97$export$2e2bcd8739ae039);
35
40
  $parcel$export(module.exports, "useCollection", () => $5ca5f7e9fc1c3544$export$2e2bcd8739ae039);
41
+ $parcel$export(module.exports, "useTypedCollection", () => $c778e69ff9ab90c6$export$2e2bcd8739ae039);
36
42
  $parcel$export(module.exports, "useInbox", () => $486f741c94cd8f74$export$2e2bcd8739ae039);
37
43
  $parcel$export(module.exports, "useNodeinfo", () => $59fc2d2cba62bd8e$export$2e2bcd8739ae039);
38
44
  $parcel$export(module.exports, "useOutbox", () => $456aea3814dded7d$export$2e2bcd8739ae039);
39
- $parcel$export(module.exports, "useWebfinger", () => $5b61553556e35016$export$2e2bcd8739ae039);
40
- $parcel$export(module.exports, "useMentions", () => $968ea07fb81eda0b$export$2e2bcd8739ae039);
41
- $parcel$export(module.exports, "ACTIVITY_TYPES", () => $ebea823cebb2f44b$export$1ec8e53e7d982d22);
42
- $parcel$export(module.exports, "ACTOR_TYPES", () => $ebea823cebb2f44b$export$9649665d7ccb0dc2);
43
- $parcel$export(module.exports, "OBJECT_TYPES", () => $ebea823cebb2f44b$export$c49cfb2681596b20);
44
- $parcel$export(module.exports, "PUBLIC_URI", () => $ebea823cebb2f44b$export$4d8d554031975581);
45
+ $parcel$export(module.exports, "useWebfinger", () => $10f3abf411a5e9d4$export$2e2bcd8739ae039);
46
+ $parcel$export(module.exports, "useMentions", () => $351e26ed1a2af792$export$2e2bcd8739ae039);
47
+ $parcel$export(module.exports, "ACTIVITY_TYPES", () => $ca4f6bb216ebdfdd$export$1ec8e53e7d982d22);
48
+ $parcel$export(module.exports, "ACTOR_TYPES", () => $ca4f6bb216ebdfdd$export$9649665d7ccb0dc2);
49
+ $parcel$export(module.exports, "OBJECT_TYPES", () => $ca4f6bb216ebdfdd$export$c49cfb2681596b20);
50
+ $parcel$export(module.exports, "PUBLIC_URI", () => $ca4f6bb216ebdfdd$export$4d8d554031975581);
45
51
  // Components
46
52
 
47
53
 
@@ -56,7 +62,7 @@ $parcel$export(module.exports, "PUBLIC_URI", () => $ebea823cebb2f44b$export$4d8d
56
62
 
57
63
 
58
64
 
59
- const $ebea823cebb2f44b$export$1ec8e53e7d982d22 = {
65
+ const $ca4f6bb216ebdfdd$export$1ec8e53e7d982d22 = {
60
66
  ACCEPT: 'Accept',
61
67
  ADD: 'Add',
62
68
  ANNOUNCE: 'Announce',
@@ -86,14 +92,14 @@ const $ebea823cebb2f44b$export$1ec8e53e7d982d22 = {
86
92
  UPDATE: 'Update',
87
93
  VIEW: 'View'
88
94
  };
89
- const $ebea823cebb2f44b$export$9649665d7ccb0dc2 = {
95
+ const $ca4f6bb216ebdfdd$export$9649665d7ccb0dc2 = {
90
96
  APPLICATION: 'Application',
91
97
  GROUP: 'Group',
92
98
  ORGANIZATION: 'Organization',
93
99
  PERSON: 'Person',
94
100
  SERVICE: 'Service'
95
101
  };
96
- const $ebea823cebb2f44b$export$c49cfb2681596b20 = {
102
+ const $ca4f6bb216ebdfdd$export$c49cfb2681596b20 = {
97
103
  ARTICLE: 'Article',
98
104
  AUDIO: 'Audio',
99
105
  DOCUMENT: 'Document',
@@ -107,7 +113,11 @@ const $ebea823cebb2f44b$export$c49cfb2681596b20 = {
107
113
  TOMBSTONE: 'Tombstone',
108
114
  VIDEO: 'Video'
109
115
  };
110
- const $ebea823cebb2f44b$export$4d8d554031975581 = 'https://www.w3.org/ns/activitystreams#Public';
116
+ const $ca4f6bb216ebdfdd$export$4d8d554031975581 = 'https://www.w3.org/ns/activitystreams#Public';
117
+
118
+
119
+
120
+
111
121
 
112
122
 
113
123
 
@@ -138,6 +148,45 @@ const $03510abb28fd3d8a$export$34aed805e991a647 = (iterable, predicate)=>{
138
148
  return true;
139
149
  });
140
150
  };
151
+ const $03510abb28fd3d8a$export$2684df65fa35e98e = async (jsonLdObject)=>{
152
+ // Convert JSON-LD object to N-Quads string
153
+ const nquads = await (0, ($parcel$interopDefault($583VT$jsonld))).toRDF(jsonLdObject, {
154
+ format: 'application/n-quads'
155
+ });
156
+ // Parse N-Quads string to RDF/JS quads
157
+ const parser = new (0, ($parcel$interopDefault($583VT$rdfjsparsern3)))();
158
+ const quadStream = parser.import((0, $583VT$readablestream.Readable).from([
159
+ nquads
160
+ ]));
161
+ const dataset = await (0, ($parcel$interopDefault($583VT$rdfext))).dataset().import(quadStream);
162
+ return dataset;
163
+ };
164
+ const $03510abb28fd3d8a$export$7089f01fea2fc5c2 = async (jsonLdObject)=>{
165
+ // Convert JSON-LD object to N-Quads string
166
+ const nquads = await (0, ($parcel$interopDefault($583VT$jsonld))).toRDF(jsonLdObject, {
167
+ format: 'application/n-quads'
168
+ });
169
+ // Parse N-Quads string to RDF/JS quads
170
+ const parser = new (0, ($parcel$interopDefault($583VT$rdfjsparsern3)))();
171
+ const quadStream = parser.import((0, $583VT$readablestream.Readable).from([
172
+ nquads
173
+ ]));
174
+ // Convert the quad stream to an array of quads
175
+ const quads = [];
176
+ quadStream.on('data', (quad)=>{
177
+ quads.push(quad);
178
+ });
179
+ return new Promise((resolve, reject)=>{
180
+ quadStream.on('end', ()=>{
181
+ resolve(quads);
182
+ });
183
+ quadStream.on('error', (error)=>{
184
+ reject(error);
185
+ });
186
+ });
187
+ };
188
+
189
+
141
190
 
142
191
 
143
192
 
@@ -145,10 +194,8 @@ const $03510abb28fd3d8a$export$34aed805e991a647 = (iterable, predicate)=>{
145
194
 
146
195
 
147
196
 
148
- // Cache of SHACL validators
149
- const $24b34de916fb30a8$var$validatorCache = {};
150
197
  // Helper function to convert a string to a Node.js Readable stream
151
- const $24b34de916fb30a8$var$stringToStream = (str)=>{
198
+ const $a370eba7b7eca32b$export$7b2e5d6b7377fcaf = (str)=>{
152
199
  // Create a TextEncoder to convert string to Uint8Array
153
200
  const encoder = new TextEncoder();
154
201
  const uint8Array = encoder.encode(str);
@@ -162,82 +209,135 @@ const $24b34de916fb30a8$var$stringToStream = (str)=>{
162
209
  // Convert the web ReadableStream to a Node.js Readable stream
163
210
  return new (0, $583VT$readablewebtonodestream.ReadableWebToNodeStream)(readableStream);
164
211
  };
165
- // Helper function to parse JSON-LD and convert to RDF-ext quads
166
- const $24b34de916fb30a8$export$2684df65fa35e98e = async (jsonLdObj, context)=>{
212
+ const $a370eba7b7eca32b$export$7304a15200aa09e5 = async (turtleData)=>{
213
+ // Convert Turtle data to a stream
214
+ const textStream = $a370eba7b7eca32b$export$7b2e5d6b7377fcaf(turtleData);
215
+ // Use ParserN3 which outputs rdf-ext compatible quads directly
216
+ const parser = new (0, ($parcel$interopDefault($583VT$rdfjsparsern3)))({
217
+ factory: (0, ($parcel$interopDefault($583VT$rdfext)))
218
+ });
219
+ const quadStream = parser.import(textStream);
220
+ const dataset = await (0, ($parcel$interopDefault($583VT$rdfext))).dataset().import(quadStream);
221
+ return dataset;
222
+ };
223
+
224
+
225
+ const $24b34de916fb30a8$var$activitystreams = (0, $583VT$activitypodsshapedefinitions.jsonld).activitystreams;
226
+ // Cache of SHACL validators
227
+ const $24b34de916fb30a8$var$validatorCache = {};
228
+ /**
229
+ * Returns a SHACL validator for ActivityStreams shapes.
230
+ *
231
+ * This function creates a SHACL validator for ActivityStreams shapes using the
232
+ * `@activitypods/shape-definitions` package. It caches the validator to avoid
233
+ * creating it multiple times.
234
+ *
235
+ * @returns A Promise that resolves to a SHACL Validator instance.
236
+ */ const $24b34de916fb30a8$export$8b707c2a07270e94 = async ()=>{
237
+ // Check if the validator is already cached
238
+ if ($24b34de916fb30a8$var$validatorCache.activityStreams) return $24b34de916fb30a8$var$validatorCache.activityStreams;
167
239
  try {
168
- // Add context to the JSON-LD object if needed
169
- const jsonLdWithContext = {
170
- ...jsonLdObj,
171
- '@context': context
172
- };
173
- // Convert JSON-LD object to string
174
- const jsonString = JSON.stringify(jsonLdWithContext);
175
- // Convert string to stream using the helper function
176
- const textStream = $24b34de916fb30a8$var$stringToStream(jsonString);
177
- // Use the JsonLdParser that outputs rdf-ext compatible quads directly
178
- const parser = new (0, ($parcel$interopDefault($583VT$rdfjsparserjsonld)))({
179
- factory: (0, ($parcel$interopDefault($583VT$rdfext)))
240
+ const shapeDataset = await (0, $a370eba7b7eca32b$export$7304a15200aa09e5)($24b34de916fb30a8$var$activitystreams);
241
+ // Create and cache the SHACL validator using the dataset
242
+ $24b34de916fb30a8$var$validatorCache.activityStreams = new (0, $583VT$shaclengine.Validator)(shapeDataset, {
243
+ factory: (0, ($parcel$interopDefault($583VT$rdfext))),
244
+ debug: true
180
245
  });
181
- const quadStream = parser.import(textStream);
182
- // Collect quads into a dataset
183
- const dataset = (0, ($parcel$interopDefault($583VT$rdfext))).dataset();
184
- for await (const quad of quadStream)dataset.add(quad);
185
- return dataset;
246
+ return $24b34de916fb30a8$var$validatorCache.activityStreams;
186
247
  } catch (error) {
187
- console.error('Error parsing JSON-LD:', error);
188
- throw error;
248
+ throw new Error(`Failed to create ActivityStreams validator: ${error instanceof Error ? error.message : 'Unknown error'}`);
189
249
  }
250
+ const shapeDataset = await (0, $a370eba7b7eca32b$export$7304a15200aa09e5)($24b34de916fb30a8$var$activitystreams);
251
+ // Create and cache the SHACL validator using the dataset
252
+ $24b34de916fb30a8$var$validatorCache.activityStreams = new (0, $583VT$shaclengine.Validator)(shapeDataset, {
253
+ factory: (0, ($parcel$interopDefault($583VT$rdfext))),
254
+ debug: true
255
+ });
256
+ return $24b34de916fb30a8$var$validatorCache.activitystreams;
190
257
  };
191
258
  // Helper function to load a SHACL shape and return a validator
192
259
  const $24b34de916fb30a8$export$6de257db5bb9fd74 = async (shapeUri)=>{
193
260
  // Check if the validator is already cached
194
261
  if ($24b34de916fb30a8$var$validatorCache[shapeUri]) return $24b34de916fb30a8$var$validatorCache[shapeUri];
195
- const response = await fetch(shapeUri, {
196
- headers: {
197
- Accept: 'text/turtle'
198
- }
199
- });
200
- if (!response.ok) throw new Error(`Failed to load shape: ${response.status} ${response.statusText}`);
201
- // Get the Turtle data as text
202
- const turtleData = await response.text();
203
- // Convert text to stream using the helper function
204
- const textStream = $24b34de916fb30a8$var$stringToStream(turtleData);
205
- // Use ParserN3 which outputs rdf-ext compatible quads directly
206
- const parser = new (0, ($parcel$interopDefault($583VT$rdfjsparsern3)))({
207
- factory: (0, ($parcel$interopDefault($583VT$rdfext)))
208
- });
209
- const quadStream = parser.import(textStream);
210
- // Collect quads into a dataset
211
- const shapeDataset = (0, ($parcel$interopDefault($583VT$rdfext))).dataset();
212
- for await (const quad of quadStream)shapeDataset.add(quad);
213
- // Create and cache the SHACL validator using the dataset
214
- $24b34de916fb30a8$var$validatorCache[shapeUri] = new (0, ($parcel$interopDefault($583VT$rdfvalidateshacl)))(shapeDataset, {
215
- factory: (0, ($parcel$interopDefault($583VT$rdfext)))
216
- });
217
- return $24b34de916fb30a8$var$validatorCache[shapeUri];
262
+ try {
263
+ const response = await fetch(shapeUri, {
264
+ headers: {
265
+ Accept: 'text/turtle'
266
+ }
267
+ });
268
+ if (!response.ok) throw new Error(`Failed to load shape: ${response.status} ${response.statusText}`);
269
+ // Get the Turtle data as text
270
+ const turtleData = await response.text();
271
+ const shapeDataset = await (0, $a370eba7b7eca32b$export$7304a15200aa09e5)(turtleData);
272
+ // Create and cache the SHACL validator using the dataset
273
+ $24b34de916fb30a8$var$validatorCache[shapeUri] = new (0, $583VT$shaclengine.Validator)(shapeDataset, {
274
+ factory: (0, ($parcel$interopDefault($583VT$rdfext)))
275
+ });
276
+ return $24b34de916fb30a8$var$validatorCache[shapeUri];
277
+ } catch (error) {
278
+ throw new Error(`Failed to create SHACL validator for ${shapeUri}: ${error instanceof Error ? error.message : 'Unknown error'}`);
279
+ }
218
280
  };
219
- const $24b34de916fb30a8$export$1558e55ae3912bbb = async (items, shaclValidator, context)=>{
281
+ /**
282
+ * Validates an array of items against a SHACL shape and returns the validation results.
283
+ *
284
+ * @param items The items to validate
285
+ * @param shaclValidator The SHACL validator to use
286
+ * @param context The context to use for the items
287
+ *
288
+ * @returns An array of objects containing the item and its validation result
289
+ */ const $24b34de916fb30a8$export$1558e55ae3912bbb = async (items, shaclValidator, context)=>{
220
290
  if (!shaclValidator) throw new Error('validateItems: shaclValidator is required');
221
- if (!context) throw new Error('validateItems: context is required');
222
291
  return Promise.all(items.map(async (item)=>{
223
292
  try {
293
+ if (!item['@context']) item['@context'] = context;
224
294
  // Create a dataset from the item's JSON-LD
225
- const itemDataset = await $24b34de916fb30a8$export$2684df65fa35e98e(item, context);
295
+ const itemDataset = await (0, $03510abb28fd3d8a$export$2684df65fa35e98e)(item);
226
296
  // Validate against the SHACL shape
227
- const report = shaclValidator?.validate(itemDataset);
297
+ const report = shaclValidator.validate({
298
+ dataset: itemDataset
299
+ });
228
300
  return {
229
301
  item: item,
230
- isValid: report?.conforms
302
+ isValid: report.conforms
231
303
  };
232
304
  } catch (error) {
233
- console.error(`Error validating item ${item.id}:`, error);
234
305
  return {
235
306
  item: item,
236
- isValid: false
307
+ isValid: false,
308
+ error: error
237
309
  };
238
310
  }
239
311
  }));
240
312
  };
313
+ /**
314
+ * Validates a subject against a set of SHACL shapes and returns the typed item if valid.
315
+ *
316
+ * @param subjectUri The subject to validate
317
+ * @param dataset The dataset containing the subject
318
+ * @param shapeTypes The shape types to validate against
319
+ * @param validator The SHACL validator to use
320
+ *
321
+ * @returns A typed item if valid, or null if not valid
322
+ */ const $24b34de916fb30a8$export$c4cb1062f0ffb837 = async (subjectUri, dataset, shapeTypes, validator)=>{
323
+ const validationReport = await validator.validate(// Terms means the entry point from which should be validated, in our case the current item.
324
+ {
325
+ dataset: dataset,
326
+ terms: [
327
+ (0, ($parcel$interopDefault($583VT$rdfext))).namedNode(subjectUri)
328
+ ]
329
+ }, // Here, terms means the shapes to validate against.
330
+ {
331
+ terms: shapeTypes.map((shapeType)=>(0, ($parcel$interopDefault($583VT$rdfext))).namedNode(shapeType.shape))
332
+ });
333
+ if (!validationReport.conforms) return null;
334
+ const { results: results } = validationReport;
335
+ // Find the shape that matched the item in the report results.
336
+ const shapeType = shapeTypes.find((st)=>results.find((res)=>res.focusNode === subjectUri && res.shape === st.shape));
337
+ if (!shapeType) return null;
338
+ const typedItem = dataset.usingType(shapeType).fromSubject(subjectUri);
339
+ return typedItem;
340
+ };
241
341
 
242
342
 
243
343
  // Used to avoid re-renders
@@ -255,14 +355,17 @@ const $5ca5f7e9fc1c3544$var$useItemsFromPages = (pages, dereferenceItems)=>{
255
355
  items
256
356
  ]);
257
357
  // Dereference all items, if necessary (even if shouldDereference is false, the hook needs to be called).
258
- const itemQueries = (0, $583VT$reactquery.useQueries)(!shouldDereference ? $5ca5f7e9fc1c3544$var$emptyArray : items.filter((item)=>typeof item === 'string').map((itemUri)=>({
259
- queryKey: [
260
- 'resource',
261
- itemUri
262
- ],
263
- queryFn: async ()=>(await dataProvider.fetch(itemUri)).json,
264
- staleTime: Infinity // Activities are immutable, so no need to refetch..
265
- })));
358
+ const itemQueries = (0, $583VT$tanstackreactquery.useQueries)({
359
+ queries: !shouldDereference ? $5ca5f7e9fc1c3544$var$emptyArray : items.filter((item)=>typeof item === 'string').map((itemUri)=>({
360
+ queryKey: [
361
+ 'resource',
362
+ itemUri
363
+ ],
364
+ queryFn: async ()=>(await dataProvider.fetch(itemUri)).json,
365
+ // TODO: Collections don't have to contain activities only, do they?
366
+ staleTime: Infinity // Activities are immutable, so no need to refetch..
367
+ }))
368
+ });
266
369
  if (!shouldDereference) return {
267
370
  loadedItems: items,
268
371
  isLoading: false,
@@ -281,7 +384,7 @@ const $5ca5f7e9fc1c3544$var$useItemsFromPages = (pages, dereferenceItems)=>{
281
384
  };
282
385
  };
283
386
  /**
284
- * Subscribe a collection. Supports pagination.
387
+ * Subscribe toa collection. Supports pagination.
285
388
  * @param predicateOrUrl The collection URI or the predicate to get the collection URI from the identity (webId).
286
389
  * @param {UseCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false }`
287
390
  */ const $5ca5f7e9fc1c3544$var$useCollection = (predicateOrUrl, options = {})=>{
@@ -290,7 +393,7 @@ const $5ca5f7e9fc1c3544$var$useItemsFromPages = (pages, dereferenceItems)=>{
290
393
  const [totalItems, setTotalItems] = (0, $583VT$react.useState)(0);
291
394
  const [isPaginated, setIsPaginated] = (0, $583VT$react.useState)(false); // true if the collection is paginated
292
395
  const [yieldsTotalItems, setYieldsTotalItems] = (0, $583VT$react.useState)(false); // true if the collection server yields totalItems
293
- const queryClient = (0, $583VT$reactquery.useQueryClient)();
396
+ const queryClient = (0, $583VT$tanstackreactquery.useQueryClient)();
294
397
  const [hasLiveUpdates, setHasLiveUpdates] = (0, $583VT$react.useState)({
295
398
  status: 'connecting'
296
399
  });
@@ -299,7 +402,7 @@ const $5ca5f7e9fc1c3544$var$useItemsFromPages = (pages, dereferenceItems)=>{
299
402
  // Get collectionUrl from webId predicate or URL.
300
403
  const collectionUrl = (0, $583VT$react.useMemo)(()=>{
301
404
  if (predicateOrUrl) {
302
- if (predicateOrUrl.startsWith('http')) return predicateOrUrl;
405
+ if (predicateOrUrl.startsWith('http') || predicateOrUrl.startsWith('did:ng:')) return predicateOrUrl;
303
406
  if (identity?.webIdData) return identity?.webIdData?.[predicateOrUrl];
304
407
  }
305
408
  return undefined;
@@ -348,6 +451,8 @@ const $5ca5f7e9fc1c3544$var$useItemsFromPages = (pages, dereferenceItems)=>{
348
451
  // Validate the json with the SHACL shape
349
452
  if (shaclShapeUri !== '' && json[itemsKey] && json[itemsKey].length > 0) try {
350
453
  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.`);
454
+ // TODO: Research: Is this used with the multi-purpose viewer already?
455
+ // How can multiple shapes be validated? Can we get this typed here?
351
456
  const shaclValidator = await (0, $24b34de916fb30a8$export$6de257db5bb9fd74)(shaclShapeUri);
352
457
  const validatedResults = await (0, $24b34de916fb30a8$export$1558e55ae3912bbb)((0, $03510abb28fd3d8a$export$e57ff0f701c44363)(json[itemsKey]), shaclValidator, json['@context']);
353
458
  // Keep only the valid item in the collection
@@ -366,16 +471,19 @@ const $5ca5f7e9fc1c3544$var$useItemsFromPages = (pages, dereferenceItems)=>{
366
471
  shaclShapeUri
367
472
  ]);
368
473
  // Use infiniteQuery to handle pagination, fetching, etc.
369
- const { data: pageData, error: collectionError, fetchNextPage: fetchNextPage, refetch: refetch, hasNextPage: hasNextPage, isLoading: isLoadingPage, isFetching: isFetchingPage, isFetchingNextPage: isFetchingNextPage } = (0, $583VT$reactquery.useInfiniteQuery)([
370
- 'collection',
371
- {
372
- collectionUrl: collectionUrl,
373
- shaclShapeUri: shaclShapeUri
374
- }
375
- ], fetchCollection, {
474
+ const { data: pageData, error: collectionError, fetchNextPage: fetchNextPage, refetch: refetch, hasNextPage: hasNextPage, isLoading: isLoadingPage, isFetching: isFetchingPage, isFetchingNextPage: isFetchingNextPage } = (0, $583VT$tanstackreactquery.useInfiniteQuery)({
475
+ queryKey: [
476
+ 'collection',
477
+ {
478
+ collectionUrl: collectionUrl,
479
+ shaclShapeUri: shaclShapeUri
480
+ }
481
+ ],
376
482
  enabled: !!(collectionUrl && identity?.id),
483
+ initialPageParam: collectionUrl,
377
484
  getNextPageParam: (lastPage)=>lastPage.next,
378
- getPreviousPageParam: (firstPage)=>firstPage.prev
485
+ getPreviousPageParam: (firstPage)=>firstPage.prev,
486
+ queryFn: fetchCollection
379
487
  });
380
488
  // Put all items together in a list (and dereference, if required).
381
489
  const { loadedItems: items, isLoading: isLoadingItems, isFetching: isFetchingItems, errors: itemErrors } = $5ca5f7e9fc1c3544$var$useItemsFromPages(pageData?.pages ?? $5ca5f7e9fc1c3544$var$emptyArray, dereferenceItems);
@@ -405,13 +513,14 @@ const $5ca5f7e9fc1c3544$var$useItemsFromPages = (pages, dereferenceItems)=>{
405
513
  oldData.pages = pages;
406
514
  return oldData;
407
515
  });
408
- if (shouldRefetch) setTimeout(()=>queryClient.refetchQueries([
409
- 'collection',
410
- {
411
- collectionUrl: collectionUrl
412
- }
413
- ], {
414
- active: true,
516
+ if (shouldRefetch) setTimeout(async ()=>queryClient.refetchQueries({
517
+ queryKey: [
518
+ 'collection',
519
+ {
520
+ collectionUrl: collectionUrl
521
+ }
522
+ ],
523
+ type: 'active',
415
524
  exact: true
416
525
  }), typeof shouldRefetch === 'number' ? shouldRefetch : 2000);
417
526
  }, [
@@ -443,13 +552,14 @@ const $5ca5f7e9fc1c3544$var$useItemsFromPages = (pages, dereferenceItems)=>{
443
552
  oldData.pages = pages;
444
553
  return oldData;
445
554
  });
446
- if (shouldRefetch) setTimeout(()=>queryClient.refetchQueries([
447
- 'collection',
448
- {
449
- collectionUrl: collectionUrl
450
- }
451
- ], {
452
- active: true,
555
+ if (shouldRefetch) setTimeout(()=>queryClient.refetchQueries({
556
+ queryKey: [
557
+ 'collection',
558
+ {
559
+ collectionUrl: collectionUrl
560
+ }
561
+ ],
562
+ type: 'active',
453
563
  exact: true
454
564
  }), typeof shouldRefetch === 'number' ? shouldRefetch : 2000);
455
565
  }, [
@@ -655,7 +765,7 @@ var $456aea3814dded7d$export$2e2bcd8739ae039 = $456aea3814dded7d$var$useOutbox;
655
765
  // Fix a bug in the current version of the mention extension
656
766
  // (The { id, label } object is located inside the id property)
657
767
  // See https://github.com/ueberdosis/tiptap/pull/1322
658
- const $9b1343b281972d72$var$CustomMention = (0, ($parcel$interopDefault($583VT$tiptapextensionmention))).extend({
768
+ const $b8eb0286f5686802$var$CustomMention = (0, ($parcel$interopDefault($583VT$tiptapextensionmention))).extend({
659
769
  renderHTML ({ node: node, HTMLAttributes: HTMLAttributes }) {
660
770
  return [
661
771
  'span',
@@ -696,10 +806,10 @@ const $9b1343b281972d72$var$CustomMention = (0, ($parcel$interopDefault($583VT$t
696
806
  };
697
807
  }
698
808
  });
699
- var $9b1343b281972d72$export$2e2bcd8739ae039 = $9b1343b281972d72$var$CustomMention;
809
+ var $b8eb0286f5686802$export$2e2bcd8739ae039 = $b8eb0286f5686802$var$CustomMention;
700
810
 
701
811
 
702
- const $703eba3e46be7ee5$var$useStyles = (0, ($parcel$interopDefault($583VT$muistylesmakeStyles)))((theme)=>({
812
+ const $a2b68b573919c8a3$var$useStyles = (0, $583VT$tssreactmui.makeStyles)()((theme)=>({
703
813
  form: {
704
814
  marginTop: -12 // Negative margin to keep the form close to the label
705
815
  },
@@ -745,12 +855,12 @@ const $703eba3e46be7ee5$var$useStyles = (0, ($parcel$interopDefault($583VT$muist
745
855
  marginBottom: 15
746
856
  }
747
857
  }));
748
- const $703eba3e46be7ee5$var$EmptyToolbar = ()=>null;
749
- const $703eba3e46be7ee5$var$PostCommentForm = ({ context: context, placeholder: placeholder, helperText: helperText, mentions: mentions, userResource: userResource, addItem: addItem, removeItem: removeItem })=>{
858
+ const $a2b68b573919c8a3$var$EmptyToolbar = ()=>null;
859
+ const $a2b68b573919c8a3$var$PostCommentForm = ({ context: context, placeholder: placeholder, helperText: helperText, mentions: mentions, userResource: userResource, addItem: addItem, removeItem: removeItem })=>{
750
860
  const record = (0, $583VT$reactadmin.useRecordContext)();
751
861
  const { data: identity, isLoading: isLoading } = (0, $583VT$reactadmin.useGetIdentity)();
752
862
  const userDataModel = (0, $583VT$semappssemanticdataprovider.useDataModel)(userResource);
753
- const classes = $703eba3e46be7ee5$var$useStyles();
863
+ const { classes: classes } = $a2b68b573919c8a3$var$useStyles();
754
864
  const notify = (0, $583VT$reactadmin.useNotify)();
755
865
  const outbox = (0, $456aea3814dded7d$export$2e2bcd8739ae039)();
756
866
  const [expanded, setExpanded] = (0, $583VT$react.useState)(false);
@@ -760,11 +870,14 @@ const $703eba3e46be7ee5$var$PostCommentForm = ({ context: context, placeholder:
760
870
  const mentions = Array.from(document.body.getElementsByClassName('mention'));
761
871
  const mentionedUsersUris = [];
762
872
  mentions.forEach((node)=>{
873
+ // @ts-expect-error TS(7015): Element implicitly has an 'any' type because index... Remove this comment to see the full error message
763
874
  const userUri = node.attributes['data-mention-id'].value;
875
+ // @ts-expect-error TS(7015): Element implicitly has an 'any' type because index... Remove this comment to see the full error message
764
876
  const userLabel = node.attributes['data-mention-label'].value;
765
877
  const link = document.createElement('a');
766
878
  link.setAttribute('href', `${new URL(window.location.href).origin}/${userResource}/${encodeURIComponent(userUri)}/show`);
767
879
  link.textContent = `@${userLabel}`;
880
+ // @ts-expect-error TS(2531): Object is possibly 'null'.
768
881
  node.parentNode.replaceChild(link, node);
769
882
  mentionedUsersUris.push(userUri);
770
883
  });
@@ -774,10 +887,10 @@ const $703eba3e46be7ee5$var$PostCommentForm = ({ context: context, placeholder:
774
887
  else {
775
888
  const tempId = Date.now();
776
889
  const note = {
777
- type: (0, $ebea823cebb2f44b$export$c49cfb2681596b20).NOTE,
890
+ type: (0, $ca4f6bb216ebdfdd$export$c49cfb2681596b20).NOTE,
778
891
  attributedTo: outbox.owner,
779
892
  content: document.body.innerHTML,
780
- inReplyTo: record[context],
893
+ inReplyTo: record?.[context],
781
894
  published: new Date().toISOString()
782
895
  };
783
896
  try {
@@ -791,7 +904,7 @@ const $703eba3e46be7ee5$var$PostCommentForm = ({ context: context, placeholder:
791
904
  ...note,
792
905
  to: [
793
906
  ...mentionedUsersUris,
794
- (0, $ebea823cebb2f44b$export$4d8d554031975581)
907
+ (0, $ca4f6bb216ebdfdd$export$4d8d554031975581)
795
908
  ]
796
909
  });
797
910
  notify("Commentaire post\xe9 avec succ\xe8s", {
@@ -830,13 +943,15 @@ const $703eba3e46be7ee5$var$PostCommentForm = ({ context: context, placeholder:
830
943
  onClick: openAuthIfDisconnected,
831
944
  children: [
832
945
  /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)((0, $583VT$muimaterial.Avatar), {
833
- src: identity?.webIdData?.[userDataModel?.fieldsMapping?.image] || identity?.profileData?.[userDataModel?.fieldsMapping?.image],
946
+ src: // @ts-expect-error TS(2339): Property 'image' does not exist on type '{ title: ... Remove this comment to see the full error message
947
+ 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
948
+ identity?.profileData?.[userDataModel?.fieldsMapping?.image],
834
949
  className: classes.avatar
835
950
  }),
836
951
  /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)((0, $583VT$rainputrichtext.RichTextInput), {
837
952
  source: "comment",
838
953
  label: " ",
839
- toolbar: /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)($703eba3e46be7ee5$var$EmptyToolbar, {}),
954
+ toolbar: /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)($a2b68b573919c8a3$var$EmptyToolbar, {}),
840
955
  fullWidth: true,
841
956
  classes: {
842
957
  editorContent: classes.editorContent
@@ -847,11 +962,12 @@ const $703eba3e46be7ee5$var$PostCommentForm = ({ context: context, placeholder:
847
962
  setExpanded(true);
848
963
  },
849
964
  extensions: [
965
+ // @ts-expect-error TS(2461): Type 'Extensions | undefined' is not an array type... Remove this comment to see the full error message
850
966
  ...(0, $583VT$rainputrichtext.DefaultEditorOptions).extensions,
851
967
  placeholder ? (0, ($parcel$interopDefault($583VT$tiptapextensionplaceholder))).configure({
852
968
  placeholder: placeholder
853
969
  }) : null,
854
- mentions ? (0, $9b1343b281972d72$export$2e2bcd8739ae039).configure({
970
+ mentions ? (0, $b8eb0286f5686802$export$2e2bcd8739ae039).configure({
855
971
  HTMLAttributes: {
856
972
  class: 'mention'
857
973
  },
@@ -883,7 +999,7 @@ const $703eba3e46be7ee5$var$PostCommentForm = ({ context: context, placeholder:
883
999
  ]
884
1000
  });
885
1001
  };
886
- var $703eba3e46be7ee5$export$2e2bcd8739ae039 = $703eba3e46be7ee5$var$PostCommentForm;
1002
+ var $a2b68b573919c8a3$export$2e2bcd8739ae039 = $a2b68b573919c8a3$var$PostCommentForm;
887
1003
 
888
1004
 
889
1005
 
@@ -893,7 +1009,7 @@ var $703eba3e46be7ee5$export$2e2bcd8739ae039 = $703eba3e46be7ee5$var$PostComment
893
1009
 
894
1010
 
895
1011
 
896
- const $d68cd57b2d06b6d5$var$useStyles = (0, ($parcel$interopDefault($583VT$muistylesmakeStyles)))(()=>({
1012
+ const $0120d12473c65b5c$var$useStyles = (0, $583VT$tssreactmui.makeStyles)()(()=>({
897
1013
  container: {
898
1014
  paddingLeft: 80,
899
1015
  marginTop: 8,
@@ -937,13 +1053,13 @@ const $d68cd57b2d06b6d5$var$useStyles = (0, ($parcel$interopDefault($583VT$muist
937
1053
  marginTop: 5
938
1054
  }
939
1055
  }));
940
- const $d68cd57b2d06b6d5$var$CommentsList = ({ comments: comments, userResource: userResource, loading: loading })=>{
941
- const classes = $d68cd57b2d06b6d5$var$useStyles();
1056
+ const $0120d12473c65b5c$var$CommentsList = ({ comments: comments, userResource: userResource, loading: loading })=>{
1057
+ const { classes: classes } = $0120d12473c65b5c$var$useStyles();
942
1058
  const userDataModel = (0, $583VT$semappssemanticdataprovider.useDataModel)(userResource);
943
1059
  return /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsxs)((0, $583VT$muimaterial.Box), {
944
1060
  position: "relative",
945
1061
  children: [
946
- comments && comments.sort((a, b)=>new Date(b.published) - new Date(a.published)).map((comment)=>/*#__PURE__*/ (0, $583VT$reactjsxruntime.jsxs)((0, $583VT$muimaterial.Box), {
1062
+ comments && comments.sort((a, b)=>new Date(b.published).getTime() - new Date(a.published).getTime()).map((comment)=>/*#__PURE__*/ (0, $583VT$reactjsxruntime.jsxs)((0, $583VT$muimaterial.Box), {
947
1063
  className: classes.container,
948
1064
  children: [
949
1065
  /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)((0, $583VT$muimaterial.Box), {
@@ -971,7 +1087,7 @@ const $d68cd57b2d06b6d5$var$CommentsList = ({ comments: comments, userResource:
971
1087
  linkType: "show",
972
1088
  children: /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)((0, $583VT$reactadmin.TextField), {
973
1089
  variant: "body2",
974
- source: userDataModel?.fieldsMapping?.title,
1090
+ source: userDataModel?.fieldsMapping?.title || '',
975
1091
  className: classes.label
976
1092
  })
977
1093
  }),
@@ -1008,17 +1124,19 @@ const $d68cd57b2d06b6d5$var$CommentsList = ({ comments: comments, userResource:
1008
1124
  ]
1009
1125
  });
1010
1126
  };
1011
- var $d68cd57b2d06b6d5$export$2e2bcd8739ae039 = $d68cd57b2d06b6d5$var$CommentsList;
1127
+ var $0120d12473c65b5c$export$2e2bcd8739ae039 = $0120d12473c65b5c$var$CommentsList;
1012
1128
 
1013
1129
 
1014
1130
 
1015
- const $2e5504cc4159ca8d$var$CommentsField = ({ source: source, context: context, helperText: helperText, placeholder: placeholder, userResource: userResource, mentions: mentions })=>{
1131
+ const $484cf98a20a766f7$var$CommentsField = ({ source: source = 'id', context: context = 'id', helperText: helperText, placeholder: placeholder = "Commencez \xe0 taper votre commentaire...", userResource: userResource, mentions: mentions })=>{
1016
1132
  const record = (0, $583VT$reactadmin.useRecordContext)();
1017
- const { items: comments, loading: loading, addItem: addItem, removeItem: removeItem } = (0, $5ca5f7e9fc1c3544$export$2e2bcd8739ae039)(record.replies);
1133
+ const { items: comments, isLoading: isLoading, addItem: addItem, removeItem: removeItem } = (0, $5ca5f7e9fc1c3544$export$2e2bcd8739ae039)(record?.replies, {
1134
+ liveUpdates: true
1135
+ });
1018
1136
  if (!userResource) throw new Error('No userResource defined for CommentsField');
1019
1137
  return /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsxs)((0, $583VT$reactjsxruntime.Fragment), {
1020
1138
  children: [
1021
- /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)((0, $703eba3e46be7ee5$export$2e2bcd8739ae039), {
1139
+ /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)((0, $a2b68b573919c8a3$export$2e2bcd8739ae039), {
1022
1140
  context: context,
1023
1141
  helperText: helperText,
1024
1142
  userResource: userResource,
@@ -1027,28 +1145,22 @@ const $2e5504cc4159ca8d$var$CommentsField = ({ source: source, context: context,
1027
1145
  addItem: addItem,
1028
1146
  removeItem: removeItem
1029
1147
  }),
1030
- /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)((0, $d68cd57b2d06b6d5$export$2e2bcd8739ae039), {
1148
+ /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)((0, $0120d12473c65b5c$export$2e2bcd8739ae039), {
1031
1149
  comments: comments,
1032
- loading: loading,
1150
+ loading: isLoading,
1033
1151
  userResource: userResource
1034
1152
  })
1035
1153
  ]
1036
1154
  });
1037
1155
  };
1038
- $2e5504cc4159ca8d$var$CommentsField.defaultProps = {
1039
- label: 'Commentaires',
1040
- placeholder: "Commencez \xe0 taper votre commentaire...",
1041
- source: 'id',
1042
- context: 'id'
1043
- };
1044
- var $2e5504cc4159ca8d$export$2e2bcd8739ae039 = $2e5504cc4159ca8d$var$CommentsField;
1156
+ var $484cf98a20a766f7$export$2e2bcd8739ae039 = $484cf98a20a766f7$var$CommentsField;
1045
1157
 
1046
1158
 
1047
1159
 
1048
1160
 
1049
1161
 
1050
1162
 
1051
- const $505d598a33288aad$var$CollectionList = ({ collectionUrl: collectionUrl, resource: resource, children: children })=>{
1163
+ const $78e7af8b8abfe6a7$var$CollectionList = ({ collectionUrl: collectionUrl, resource: resource, children: children })=>{
1052
1164
  if ((0, ($parcel$interopDefault($583VT$react))).Children.count(children) !== 1) throw new Error('<CollectionList> only accepts a single child');
1053
1165
  const { items: actorsUris } = (0, $5ca5f7e9fc1c3544$export$2e2bcd8739ae039)(collectionUrl);
1054
1166
  const { data: data, isLoading: isLoading, isFetching: isFetching } = (0, $583VT$reactadmin.useGetMany)(resource, {
@@ -1068,31 +1180,302 @@ const $505d598a33288aad$var$CollectionList = ({ collectionUrl: collectionUrl, re
1068
1180
  children: children
1069
1181
  });
1070
1182
  };
1071
- var $505d598a33288aad$export$2e2bcd8739ae039 = $505d598a33288aad$var$CollectionList;
1183
+ var $78e7af8b8abfe6a7$export$2e2bcd8739ae039 = $78e7af8b8abfe6a7$var$CollectionList;
1072
1184
 
1073
1185
 
1074
1186
 
1075
1187
 
1076
1188
 
1077
1189
 
1078
- const $b0c94a9bdea99da5$var$ReferenceCollectionField = ({ source: source, reference: reference, children: children, ...rest })=>{
1190
+ const $63048bed1787ac97$var$ReferenceCollectionField = ({ source: source, reference: reference, children: children, ...rest })=>{
1079
1191
  const record = (0, $583VT$reactadmin.useRecordContext)();
1080
1192
  if ((0, ($parcel$interopDefault($583VT$react))).Children.count(children) !== 1) throw new Error('<ReferenceCollectionField> only accepts a single child');
1081
1193
  if (!record || !record[source]) return null;
1082
- return /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)((0, $505d598a33288aad$export$2e2bcd8739ae039), {
1194
+ return /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)((0, $78e7af8b8abfe6a7$export$2e2bcd8739ae039), {
1083
1195
  resource: reference,
1084
1196
  collectionUrl: record[source],
1085
1197
  ...rest,
1086
1198
  children: children
1087
1199
  });
1088
1200
  };
1089
- var $b0c94a9bdea99da5$export$2e2bcd8739ae039 = $b0c94a9bdea99da5$var$ReferenceCollectionField;
1201
+ var $63048bed1787ac97$export$2e2bcd8739ae039 = $63048bed1787ac97$var$ReferenceCollectionField;
1202
+
1203
+
1204
+
1090
1205
 
1091
1206
 
1092
1207
 
1093
1208
 
1094
1209
 
1095
1210
 
1211
+
1212
+
1213
+
1214
+
1215
+ /**
1216
+ * Subscribe to a collection. Supports pagination.
1217
+ * @param collectionUri The collection URI or the predicate to get the collection URI from the identity (webId).
1218
+ * @param {UseCollectionOptions & UseTypedCollectionOptions} options Defaults to `{ dereferenceItems: false, liveUpdates: false, pageSize: 10 }` and requires at least one ldo @see {ShapeType}.
1219
+ */ const $c778e69ff9ab90c6$var$useTypedCollection = (collectionUri, options)=>{
1220
+ const { pageSize: pageSize = 10, liveUpdates: subscribeToUpdates = false, shapeTypes: shapeTypes } = options;
1221
+ if (!shapeTypes.length) throw new Error('At least one ShapeType is required to filter the collection by.');
1222
+ // 1. Fetch the collection
1223
+ const collectionQuery = $c778e69ff9ab90c6$var$useInfiniteCollectionQuery(collectionUri);
1224
+ const { totalItems: totalItems, isPaginated: isPaginated } = $c778e69ff9ab90c6$var$useTotalItemsFromPages(collectionQuery.data);
1225
+ // 2. Filter items from the collection pages that match the given shape types.
1226
+ const filteredItems = $c778e69ff9ab90c6$var$useFilteredItemsFromPages(collectionQuery.data, shapeTypes);
1227
+ // 3. Set up notifications for live updates, if enabled.
1228
+ const liveUpdatesStatus = $c778e69ff9ab90c6$var$useSubscribeToUpdates({
1229
+ uri: collectionUri,
1230
+ enabled: subscribeToUpdates,
1231
+ onAddItem: (_item)=>{
1232
+ // Since we don't know where the item was added, we refetch the whole collection ¯\_(ツ)_/¯.
1233
+ collectionQuery.refetch();
1234
+ },
1235
+ onRemoveItem: (uri)=>{
1236
+ $c778e69ff9ab90c6$var$removeItemFromQueryData(uri, collectionQuery);
1237
+ }
1238
+ });
1239
+ // 4. Pagination logic.
1240
+ const [requestedNextItems, setRequestedNextItems] = (0, $583VT$react.useState)(pageSize);
1241
+ const [requestedPrevItems, setRequestedPrevItems] = (0, $583VT$react.useState)(0);
1242
+ // Automatically fetch next page, if more items are requested.
1243
+ (0, $583VT$react.useEffect)(()=>{
1244
+ if (requestedNextItems > filteredItems.length && collectionQuery.hasNextPage && !collectionQuery.isLoading) collectionQuery.fetchNextPage();
1245
+ }, [
1246
+ requestedNextItems,
1247
+ filteredItems.length,
1248
+ collectionQuery.hasNextPage,
1249
+ collectionQuery.isLoading
1250
+ ]);
1251
+ // Automatically fetch previous page, if more items are requested.
1252
+ (0, $583VT$react.useEffect)(()=>{
1253
+ if (requestedPrevItems > filteredItems.length && collectionQuery.hasPreviousPage && !collectionQuery.isLoading) collectionQuery.fetchPreviousPage();
1254
+ }, [
1255
+ requestedPrevItems,
1256
+ filteredItems.length,
1257
+ collectionQuery.hasPreviousPage,
1258
+ collectionQuery.isLoading
1259
+ ]);
1260
+ /** Fetch next n (filtered) items. */ const fetchNext = (0, $583VT$react.useCallback)((noItems = pageSize)=>{
1261
+ setRequestedNextItems(filteredItems.length + noItems);
1262
+ }, [
1263
+ filteredItems.length,
1264
+ pageSize
1265
+ ]);
1266
+ /** Fetch previous n (filtered) items. */ const fetchPrevious = (0, $583VT$react.useCallback)((noItems = pageSize)=>{
1267
+ setRequestedPrevItems(filteredItems.length + noItems);
1268
+ }, [
1269
+ filteredItems.length,
1270
+ pageSize
1271
+ ]);
1272
+ return {
1273
+ // TODO: Do we want to expose all properties from the collection query?
1274
+ ...collectionQuery,
1275
+ items: filteredItems,
1276
+ liveUpdatesStatus: liveUpdatesStatus,
1277
+ fetchNext: fetchNext,
1278
+ fetchPrevious: fetchPrevious,
1279
+ totalItems: totalItems,
1280
+ isPaginated: isPaginated
1281
+ };
1282
+ };
1283
+ var $c778e69ff9ab90c6$export$2e2bcd8739ae039 = $c778e69ff9ab90c6$var$useTypedCollection;
1284
+ const $c778e69ff9ab90c6$var$useSubscribeToUpdates = ({ uri: uri, enabled: enabled = true, onAddItem: onAddItem, onRemoveItem: onRemoveItem })=>{
1285
+ const { fetch: fetchFn } = (0, $583VT$reactadmin.useDataProvider)();
1286
+ const [status, setStatus] = (0, $583VT$react.useState)({
1287
+ status: enabled ? 'connecting' : 'disabled'
1288
+ });
1289
+ (0, $583VT$react.useEffect)(()=>{
1290
+ const webSocketRef = (0, $583VT$react.useRef)(null);
1291
+ // Nothing to do, return empty clean up function.
1292
+ if (!enabled || !uri) return ()=>{};
1293
+ // Create ws that listens to collectionUri changes
1294
+ (0, $583VT$semappssemanticdataprovider.getOrCreateWsChannel)(fetchFn, uri).then((ws)=>{
1295
+ webSocketRef.current = ws; // Keep a ref to the webSocket so that it can be used elsewhere
1296
+ webSocketRef.current.addEventListener('message', (event)=>{
1297
+ // TODO: correct ldo type
1298
+ const data = JSON.parse(event.data);
1299
+ if (data.type === 'Add') onAddItem(data.object);
1300
+ else if (data.type === 'Remove') onRemoveItem(data.object);
1301
+ });
1302
+ webSocketRef.current.addEventListener('error', (event)=>{
1303
+ setStatus({
1304
+ error: event,
1305
+ status: 'error'
1306
+ });
1307
+ // TODO: Retry after a while (use react query?).
1308
+ });
1309
+ webSocketRef.current.addEventListener('close', (_event)=>{
1310
+ if (!status.error) setStatus({
1311
+ status: 'closed'
1312
+ });
1313
+ });
1314
+ }).catch((error)=>{
1315
+ setStatus({
1316
+ status: 'error',
1317
+ error: error
1318
+ });
1319
+ });
1320
+ // Clean up, i.e. close channel.
1321
+ return ()=>{
1322
+ webSocketRef.current?.close();
1323
+ };
1324
+ }, [
1325
+ uri,
1326
+ enabled,
1327
+ onAddItem,
1328
+ onRemoveItem
1329
+ ]);
1330
+ return status;
1331
+ };
1332
+ const $c778e69ff9ab90c6$var$useInfiniteCollectionQuery = (collectionUri)=>{
1333
+ const { data: identity } = (0, $583VT$reactadmin.useGetIdentity)();
1334
+ const dataProvider = (0, $583VT$reactadmin.useDataProvider)();
1335
+ const { fetch: fetchFn } = dataProvider;
1336
+ const infiniteQueryData = (0, $583VT$tanstackreactquery.useInfiniteQuery)({
1337
+ queryKey: [
1338
+ 'collection',
1339
+ {
1340
+ uri: collectionUri
1341
+ }
1342
+ ],
1343
+ queryFn: $c778e69ff9ab90c6$var$getFetchCollectionPage(fetchFn),
1344
+ initialPageParam: collectionUri,
1345
+ enabled: !!(collectionUri && identity?.id),
1346
+ getNextPageParam: (current)=>current.data?.next,
1347
+ getPreviousPageParam: (current)=>current.data?.prev
1348
+ });
1349
+ return infiniteQueryData;
1350
+ };
1351
+ const $c778e69ff9ab90c6$var$getFetchCollectionPage = (fetchFn)=>async ({ pageParam: pageUri })=>{
1352
+ // Note, page is not necessarily of type OrderedCollectionPage but it is a partial in any case.
1353
+ const jsonPage = await (await fetchFn(pageUri)).json();
1354
+ if (!jsonPage || typeof jsonPage !== 'object') throw new Error(`Could not fetch page ${pageUri}. Response is invalid.`);
1355
+ const itemsKey = 'orderedItems' in jsonPage ? 'orderedItems' : 'items';
1356
+ if ((0, $03510abb28fd3d8a$export$e57ff0f701c44363)(jsonPage[itemsKey]).length === 0) // No items in page.
1357
+ return {
1358
+ itemIds: [],
1359
+ dataset: null,
1360
+ data: null
1361
+ };
1362
+ // Keep track of item ids in this order (in the rdf dataset the order is lost).
1363
+ const itemIds = (0, $03510abb28fd3d8a$export$e57ff0f701c44363)(jsonPage[itemsKey]).map((itemOrId)=>itemOrId?.['@id'] || itemOrId?.id || itemOrId).filter((item)=>item); // Ensure item is not undefined.
1364
+ // Parse the page into a dataset.
1365
+ // TODO: Move to data provider.
1366
+ const dataset = (0, $583VT$ldoconnected.createConnectedLdoDataset)([
1367
+ (0, $583VT$ldoconnectedsolid.solidConnectedPlugin)
1368
+ ]);
1369
+ dataset.setContext('solid', {
1370
+ fetch: fetchFn
1371
+ });
1372
+ dataset.addAll(await (0, $03510abb28fd3d8a$export$7089f01fea2fc5c2)(jsonPage));
1373
+ const resource = dataset.getResource(pageUri);
1374
+ if (resource.type === 'InvalidIdentifierResource') return {
1375
+ itemIds: itemIds,
1376
+ dataset: null,
1377
+ pageUri: pageUri,
1378
+ data: null
1379
+ };
1380
+ const ldoBuilder = dataset.usingType((0, $583VT$activitypodsldoshapes.OrderedCollectionPageShapeType));
1381
+ // Run a link query to ensure that all items are dereferenced (the results are kept in the dataset).
1382
+ await ldoBuilder.startLinkQuery(resource, pageUri, {
1383
+ items: true,
1384
+ orderedItems: true
1385
+ }).run({
1386
+ reload: false
1387
+ });
1388
+ return {
1389
+ dataset: dataset,
1390
+ itemIds: itemIds,
1391
+ pageUri: pageUri,
1392
+ data: ldoBuilder.fromSubject(pageUri)
1393
+ };
1394
+ };
1395
+ const $c778e69ff9ab90c6$var$useTotalItemsFromPages = (queryData)=>{
1396
+ if (!queryData?.pages.length) return {
1397
+ isPaginated: undefined,
1398
+ totalItems: undefined
1399
+ };
1400
+ const { pages: pages } = queryData;
1401
+ // Check if collection is paginated. We assume that the collection is paginated if there are pages with first, last, prev or next.
1402
+ 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));
1403
+ // Approach 1: Get total items info by checking if the page has a totalItems property.
1404
+ const totalItemsByCollectionInfo = pages.find((page)=>'totalItems' in page)?.data?.totalItems;
1405
+ if (totalItemsByCollectionInfo) return {
1406
+ totalItems: totalItemsByCollectionInfo,
1407
+ isPaginated: isPaginated
1408
+ };
1409
+ // Approach 2: If collection is not paginated, we count the number of items in the collection.
1410
+ if (!isPaginated) return {
1411
+ totalItems: pages[0].itemIds.length,
1412
+ isPaginated: isPaginated
1413
+ };
1414
+ // Approach 3: If we have the whole collection loaded, we can count the items.
1415
+ const firstPage = pages.find((page)=>page.data?.first)?.data?.first;
1416
+ const lastPage = pages.find((page)=>page.data?.last)?.data?.last;
1417
+ // We assume that all pages are loaded if the first and last page is available.
1418
+ // In that case, count all pages' items.
1419
+ if (firstPage && lastPage) return {
1420
+ isPaginated: isPaginated,
1421
+ totalItems: pages// Get length of page
1422
+ .map((page)=>page.data?.orderedItems?.size || page.data?.items?.size || 0)// Sum all page length counts.
1423
+ .reduce((prev, current)=>prev + current)
1424
+ };
1425
+ // If no approach succeeded, we return undefined.
1426
+ return {
1427
+ totalItems: undefined,
1428
+ isPaginated: isPaginated
1429
+ };
1430
+ };
1431
+ const $c778e69ff9ab90c6$var$useFilteredItemsFromPages = (queryData, shapeTypes)=>{
1432
+ const [filteredItems, setFilteredItems] = (0, $583VT$react.useState)([]);
1433
+ const filterItems = (0, $583VT$react.useCallback)(async ()=>{
1434
+ // We need to load the shacl resources and match them to the shape types.
1435
+ const validator = await (0, $24b34de916fb30a8$export$8b707c2a07270e94)();
1436
+ const pages = queryData?.pages;
1437
+ if (!pages || pages.length === 0) {
1438
+ setFilteredItems([]);
1439
+ return;
1440
+ }
1441
+ const validatedItems = await Promise.all(// For every page, ...
1442
+ queryData.pages.map(async (page)=>{
1443
+ const items = await Promise.all(// For every item in the page, ...
1444
+ page.itemIds.map(async (itemId)=>// Validate item against the shape types and return the ldo object of the correct type, if it is valid.
1445
+ page.dataset && (0, $24b34de916fb30a8$export$c4cb1062f0ffb837)(itemId, page.dataset, shapeTypes, validator))).then((results)=>results.filter((item)=>!!item)); // Filter out null items.
1446
+ return items;
1447
+ })).then((results)=>results.flat());
1448
+ // TODO: Order items by ids.
1449
+ setFilteredItems(validatedItems);
1450
+ // TODO: Cache filtered items by page, so that we don't have to re-filter them every time?
1451
+ }, [
1452
+ queryData?.pages,
1453
+ shapeTypes
1454
+ ]);
1455
+ (0, $583VT$react.useEffect)(()=>{
1456
+ filterItems();
1457
+ }, [
1458
+ filterItems
1459
+ ]);
1460
+ return filteredItems;
1461
+ };
1462
+ /** A somewhat hacky way to remove an item from the useInfiniteCollectionQuery. */ const $c778e69ff9ab90c6$var$removeItemFromQueryData = (itemUri, collectionQuery)=>{
1463
+ // Manipulate data about total items. Sorry, a bit hacky...
1464
+ collectionQuery.data?.pages.forEach((page)=>{
1465
+ if (!page.dataset) return;
1466
+ page.dataset.deleteMatches((0, ($parcel$interopDefault($583VT$rdfext))).namedNode(itemUri));
1467
+ // There might be a totalItems property in the page, so we need to update it.
1468
+ if (page.data.totalItems && Number.isInteger(page.data.totalItems)) // eslint-disable-next-line no-param-reassign
1469
+ page.data.totalItems -= 1;
1470
+ });
1471
+ }; // Open Question:
1472
+ // - 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.
1473
+ // - 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.
1474
+
1475
+
1476
+
1477
+
1478
+
1096
1479
  /**
1097
1480
  * Hook to fetch the inbox of the logged user.
1098
1481
  * Returns the same data as the useCollection hooks, plus:
@@ -1151,7 +1534,7 @@ var $59fc2d2cba62bd8e$export$2e2bcd8739ae039 = $59fc2d2cba62bd8e$var$useNodeinfo
1151
1534
 
1152
1535
 
1153
1536
 
1154
- const $5b61553556e35016$var$useWebfinger = ()=>{
1537
+ const $10f3abf411a5e9d4$var$useWebfinger = ()=>{
1155
1538
  // Post an activity to the logged user's outbox and return its URI
1156
1539
  const fetch = (0, $583VT$react.useCallback)(async (id)=>{
1157
1540
  // eslint-disable-next-line
@@ -1172,7 +1555,7 @@ const $5b61553556e35016$var$useWebfinger = ()=>{
1172
1555
  fetch: fetch
1173
1556
  };
1174
1557
  };
1175
- var $5b61553556e35016$export$2e2bcd8739ae039 = $5b61553556e35016$var$useWebfinger;
1558
+ var $10f3abf411a5e9d4$export$2e2bcd8739ae039 = $10f3abf411a5e9d4$var$useWebfinger;
1176
1559
 
1177
1560
 
1178
1561
 
@@ -1183,7 +1566,7 @@ var $5b61553556e35016$export$2e2bcd8739ae039 = $5b61553556e35016$var$useWebfinge
1183
1566
 
1184
1567
 
1185
1568
 
1186
- const $27d3788851661769$var$useStyles = (0, ($parcel$interopDefault($583VT$muistylesmakeStyles)))((theme)=>({
1569
+ const $d217d582899c7580$var$useStyles = (0, $583VT$tssreactmui.makeStyles)()((theme)=>({
1187
1570
  items: {
1188
1571
  background: '#fff',
1189
1572
  borderRadius: '0.5rem',
@@ -1208,24 +1591,29 @@ const $27d3788851661769$var$useStyles = (0, ($parcel$interopDefault($583VT$muist
1208
1591
  }
1209
1592
  }
1210
1593
  }));
1211
- var $27d3788851661769$export$2e2bcd8739ae039 = /*#__PURE__*/ (0, $583VT$react.forwardRef)((props, ref)=>{
1594
+ var $d217d582899c7580$export$2e2bcd8739ae039 = /*#__PURE__*/ (0, $583VT$react.forwardRef)((props, ref)=>{
1212
1595
  const [selectedIndex, setSelectedIndex] = (0, $583VT$react.useState)(0);
1213
- const classes = $27d3788851661769$var$useStyles();
1596
+ const { classes: classes } = $d217d582899c7580$var$useStyles();
1214
1597
  const selectItem = (index)=>{
1598
+ // @ts-expect-error TS(2339): Property 'items' does not exist on type '{}'.
1215
1599
  const item = props.items[index];
1216
- if (item) props.command({
1600
+ if (item) // @ts-expect-error TS(2339): Property 'command' does not exist on type '{}'.
1601
+ props.command({
1217
1602
  id: item
1218
1603
  });
1219
1604
  };
1220
1605
  const upHandler = ()=>{
1606
+ // @ts-expect-error TS(2339): Property 'items' does not exist on type '{}'.
1221
1607
  setSelectedIndex((selectedIndex + props.items.length - 1) % props.items.length);
1222
1608
  };
1223
1609
  const downHandler = ()=>{
1610
+ // @ts-expect-error TS(2339): Property 'items' does not exist on type '{}'.
1224
1611
  setSelectedIndex((selectedIndex + 1) % props.items.length);
1225
1612
  };
1226
1613
  const enterHandler = ()=>{
1227
1614
  selectItem(selectedIndex);
1228
1615
  };
1616
+ // @ts-expect-error TS(2339): Property 'items' does not exist on type '{}'.
1229
1617
  (0, $583VT$react.useEffect)(()=>setSelectedIndex(0), [
1230
1618
  props.items
1231
1619
  ]);
@@ -1248,7 +1636,8 @@ var $27d3788851661769$export$2e2bcd8739ae039 = /*#__PURE__*/ (0, $583VT$react.fo
1248
1636
  }));
1249
1637
  return /*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)("div", {
1250
1638
  className: classes.items,
1251
- children: props.items.length ? props.items.map((item, index)=>/*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)("button", {
1639
+ children: props.items.length ? // @ts-expect-error TS(2339): Property 'items' does not exist on type '{}'.
1640
+ props.items.map((item, index)=>/*#__PURE__*/ (0, $583VT$reactjsxruntime.jsx)("button", {
1252
1641
  className: classes.item + (index === selectedIndex ? ' selected' : ''),
1253
1642
  onClick: ()=>selectItem(index),
1254
1643
  children: item.label
@@ -1260,12 +1649,12 @@ var $27d3788851661769$export$2e2bcd8739ae039 = /*#__PURE__*/ (0, $583VT$react.fo
1260
1649
  });
1261
1650
 
1262
1651
 
1263
- const $7b7f4b18327176f8$var$renderMentions = ()=>{
1652
+ const $05d587317cba4616$var$renderMentions = ()=>{
1264
1653
  let component;
1265
1654
  let popup;
1266
1655
  return {
1267
1656
  onStart: (props)=>{
1268
- component = new (0, $583VT$tiptapreact.ReactRenderer)((0, $27d3788851661769$export$2e2bcd8739ae039), {
1657
+ component = new (0, $583VT$tiptapreact.ReactRenderer)((0, $d217d582899c7580$export$2e2bcd8739ae039), {
1269
1658
  props: props,
1270
1659
  editor: props.editor
1271
1660
  });
@@ -1298,10 +1687,10 @@ const $7b7f4b18327176f8$var$renderMentions = ()=>{
1298
1687
  }
1299
1688
  };
1300
1689
  };
1301
- var $7b7f4b18327176f8$export$2e2bcd8739ae039 = $7b7f4b18327176f8$var$renderMentions;
1690
+ var $05d587317cba4616$export$2e2bcd8739ae039 = $05d587317cba4616$var$renderMentions;
1302
1691
 
1303
1692
 
1304
- const $968ea07fb81eda0b$var$useMentions = (userResource)=>{
1693
+ const $351e26ed1a2af792$var$useMentions = (userResource)=>{
1305
1694
  const userDataModel = (0, $583VT$semappssemanticdataprovider.useDataModel)(userResource);
1306
1695
  const { data: data } = (0, $583VT$reactadmin.useGetList)(userResource, {
1307
1696
  filter: {
@@ -1316,7 +1705,7 @@ const $968ea07fb81eda0b$var$useMentions = (userResource)=>{
1316
1705
  const availableMentions = (0, $583VT$react.useMemo)(()=>{
1317
1706
  if (data) return data.map((item)=>({
1318
1707
  id: item.id,
1319
- label: item[userDataModel?.fieldsMapping?.title]
1708
+ label: item[userDataModel?.fieldsMapping?.title || '']
1320
1709
  }));
1321
1710
  }, [
1322
1711
  data
@@ -1330,10 +1719,10 @@ const $968ea07fb81eda0b$var$useMentions = (userResource)=>{
1330
1719
  ]);
1331
1720
  return {
1332
1721
  items: items,
1333
- render: (0, $7b7f4b18327176f8$export$2e2bcd8739ae039)
1722
+ render: (0, $05d587317cba4616$export$2e2bcd8739ae039)
1334
1723
  };
1335
1724
  };
1336
- var $968ea07fb81eda0b$export$2e2bcd8739ae039 = $968ea07fb81eda0b$var$useMentions;
1725
+ var $351e26ed1a2af792$export$2e2bcd8739ae039 = $351e26ed1a2af792$var$useMentions;
1337
1726
 
1338
1727
 
1339
1728