Ignore:
Timestamp:
08/11/2026 06:35:19 PM (4 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
960f015
Parents:
cb3001e
Message:

Elke collectie pagineert nu, via een helper in plaats van tien keer dezelfde regels

Vervolg op cb3001e, waar alleen de outbox eraan geloofde omdat Funkwhale daar
over viel. Robins opdracht: de rest ook, om compleetheid te garanderen. Dat is
de goede volgorde -- een foutmelding repareren waar hij valt laat de volgende
lezer op de volgende collectie stuklopen.

pagedCollection in ap-core, en daar hangen ze nu allemaal aan:

outbox followers following featured
tracks playlists playlist post-tracks
replies + de zeven guardianship-wachtrijen

De items blijven overal INLINE op de wortel; first en last wijzen naar dezelfde
pagina, want onze collecties zijn gekapt en er is er precies een. Wie ze vandaag
zonder pagineren leest -- Shaer doet dat -- merkt er niets van.

DRIE PLEKKEN DIE BEWUST AFWIJKEN, want een sleepnet is geen zorgvuldigheid:

  • de guardianship-wachtrijen krijgen hun @context van de route (queueRoute), dus daar staan de velden er met de hand bij. pagedCollection zou de context een tweede keer toevoegen.
  • de thread-collectie draagt al een ?object= in zijn id. Daar ?page= achteraan plakken pagineert niets, het herhaalt de vraag. Owner-only en door Shaer gelezen, dus geen federatiebelang.
  • followers en following geven publiek alleen een AANTAL. Die krijgen de velden juist wel: anders is "ik mag de lijst niet zien" niet te onderscheiden van een kapot antwoord -- dezelfde stille dubbelzinnigheid die we vandaag bij een ander aantroffen.

Vier tests erbij, waaronder een die bewaakt dat de helper attributedTo niet
opeet en een die bewaakt dat de wachtrijen GEEN eigen @context krijgen.

Co-Authored-By: Claude Opus 5 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/services/ActivityPubService.js

    rcb3001e raed0092  
    2929import Blocklist from './BlocklistService.js';
    3030import * as Guardianship from './guardianship/index.js';
    31 import { PUBLIC, AP_CONTEXT, safeUrl, actorId, noteId, guessMediaType, normalizeTags, tagParts, hashtagTags, buildHashtagList } from './ap-core.js';
     31import { PUBLIC, AP_CONTEXT, safeUrl, actorId, noteId, guessMediaType, normalizeTags, tagParts, hashtagTags, buildHashtagList, pagedCollection } from './ap-core.js';
    3232// Doorgeven wat hier altijd vandaan kwam, zodat elke bestaande aanroep blijft werken.
    3333export { AP_CONTEXT, actorId, noteId, guessMediaType };
     
    10431043  // wie hem vandaag leest hoort er morgen niet voor te hoeven pagineren. Er is
    10441044  // precies een pagina, dus first en last wijzen naar dezelfde.
    1045   const eerste = `${id}?page=1`;
    1046   if (page) {
    1047     return {
    1048       '@context': AP_CONTEXT,
    1049       id: eerste,
    1050       type: 'OrderedCollectionPage',
    1051       partOf: id,
    1052       totalItems: items.length,
    1053       orderedItems: items,
    1054     };
    1055   }
    1056   return {
    1057     '@context': AP_CONTEXT,
    1058     id,
    1059     type: 'OrderedCollection',
    1060     totalItems: items.length,
    1061     first: eerste,
    1062     last: eerste,
    1063     orderedItems: items,
    1064   };
     1045  return pagedCollection(id, items, { page });
    10651046}
    10661047
     
    10701051export function buildFollowers(base, site, count, items = null) {
    10711052  const id = `${actorId(base, site.slug)}/followers`;
    1072   return {
    1073     '@context': AP_CONTEXT,
    1074     id,
    1075     type: 'OrderedCollection',
    1076     totalItems: items ? items.length : (count || 0),
    1077     orderedItems: items || [], // count-only for the public; full for the owner
    1078   };
     1053  // count-only for the public; full for the owner
     1054  return pagedCollection(id, items || [], { totalItems: items ? items.length : (count || 0) });
    10791055}
    10801056
     
    10831059export function buildFollowing(base, site, count, items = null) {
    10841060  const id = `${actorId(base, site.slug)}/following`;
    1085   return {
    1086     '@context': AP_CONTEXT,
    1087     id,
    1088     type: 'OrderedCollection',
    1089     totalItems: items ? items.length : (count || 0),
    1090     orderedItems: items || [], // count-only for the public; full for the owner
    1091   };
     1061  // count-only for the public; full for the owner
     1062  return pagedCollection(id, items || [], { totalItems: items ? items.length : (count || 0) });
    10921063}
    10931064
     
    10981069  const id = `${actorId(base, site.slug)}/featured`;
    10991070  const items = (posts || []).map((p) => buildNote(base, site, p));
    1100   return {
    1101     '@context': AP_CONTEXT,
    1102     id,
    1103     type: 'OrderedCollection',
    1104     totalItems: items.length,
    1105     orderedItems: items,
    1106   };
     1071  return pagedCollection(id, items);
    11071072}
    11081073
     
    65556520
    65566521export default {
    6557   AP_CONTEXT, getOrCreateKeys, apWants, sendAP, actorId, noteId, stripLeadingMentions,
     6522  AP_CONTEXT, getOrCreateKeys, apWants, sendAP, actorId, noteId, stripLeadingMentions, pagedCollection,
    65586523  buildActor, buildNote, buildCreate, buildOutbox, buildFollowers, buildFollowing, buildFeatured,
    65596524  channelUrls, channelCategory, timelineFields, guessMediaType,
Note: See TracChangeset for help on using the changeset viewer.