Ignore:
Timestamp:
08/08/2026 04:57:37 AM (5 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
47ca083
Parents:
39a9d21
git-author:
Robin <roboburr@…> (08/08/2026 04:57:33 AM)
git-committer:
Robin <roboburr@…> (08/08/2026 04:57:37 AM)
Message:

De outbox vertelt de discografie mee (shaer-0nh, stap 4)

Een track verschijnt nu als Create(Audio) in de outbox, door de posts heen op
datum. Daarmee is een Klonkt-actor als kanaal uit te lezen: precies zoals ik
Funkwhales kanaal uitlas -- hun achttien tracks stonden in hun outbox.

WAAROM GEEN BEZORGING NAAR VOLGERS, terwijl ik stap 4 eerder zo beschreef.
Mastodon neemt Audio aan als STATUSTYPE. Publiceer je een post met een album,
dan zouden volgers de Note met spelers krijgen EN N losse Audio-statussen:
dezelfde muziek twee keer in hun tijdlijn. Dat is geen spiegel afmaken maar
andermans tijdlijn vervuilen. Een kanaal-lezer HAALT op; hij hoeft niet
geduwd te worden. De post is het bericht, de outbox is de discografie.

DE DEUR BLIJFT DICHT. buildOutbox krijgt de tracks als ARGUMENT en haalt ze
uitdrukkelijk niet zelf op. De route beslist wie wat ziet, en de blocked-tak
daar levert een outbox zonder posts EN zonder tracks. Een bouwer die stiekem
zijn eigen database bevraagt zou dwars door die dichte deur heen leveren --
dat had ik bijna gebouwd, en de tak in de route ving het pas bij nalezen.

Het id van de activiteit is stabiel (<track>#create), zodat twee keer ophalen
niet twee keer nieuws is.

5 tests.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/services/ActivityPubService.js

    r39a9d21 rfb22f78  
    945945}
    946946
    947 export function buildOutbox(base, site, posts) {
     947/**
     948 * Een track als publicatie: Create(Audio) (shaer-0nh, stap 4).
     949 *
     950 * Zelfde vorm als buildCreate voor een post, met een STABIEL id: dezelfde track
     951 * levert altijd dezelfde activiteit, zodat een lezer die de outbox twee keer
     952 * ophaalt niet denkt dat er iets nieuws is.
     953 */
     954export function buildTrackCreate(base, site, r) {
     955  const audio = buildTrackAudio(base, site, r);
     956  const me = actorId(base, site.slug);
     957  return {
     958    '@context': AP_CONTEXT,
     959    id: `${audio.id}#create`,
     960    type: 'Create',
     961    actor: me,
     962    published: audio.published,
     963    to: [PUBLIC],
     964    cc: [`${me}/followers`],
     965    object: audio,
     966  };
     967}
     968
     969/**
     970 * De outbox: wat deze actor heeft uitgebracht. Posts EN tracks (shaer-0nh,
     971 * stap 4).
     972 *
     973 * WAAROM HIER EN NIET IN EEN BEZORGING. Een kanaal-lezer HAALT de outbox op --
     974 * zo heb ik zelf Funkwhales kanaal uitgelezen. Een Create(Audio) ook naar de
     975 * inboxen van volgers duwen zou schade doen: Mastodon neemt Audio aan als
     976 * statustype, dus bij een album-post zou dezelfde muziek twee keer in hun
     977 * tijdlijn komen -- een keer als bijlage bij de Note, en dan nog N keer los.
     978 * De post is het bericht, de outbox is de discografie.
     979 *
     980 * Door elkaar op datum, nieuwste eerst, zodat de outbox één verhaal vertelt in
     981 * plaats van twee lijstjes achter elkaar.
     982 *
     983 * De tracks komen als ARGUMENT binnen, net als de posts, en worden hier
     984 * uitdrukkelijk NIET zelf opgehaald. De route beslist wie wat mag zien -- een
     985 * geblokkeerde bezoeker krijgt daar een lege outbox, en een bouwer die stiekem
     986 * zijn eigen database bevraagt zou dwars door die deur heen leveren.
     987 */
     988export function buildOutbox(base, site, posts, tracks = []) {
    948989  const id = `${actorId(base, site.slug)}/outbox`;
    949   const items = (posts || []).slice(0, MAX_OUTBOX).map((p) => buildCreate(base, site, p));
     990  const wanneer = (x) => Date.parse(x && x.published ? x.published : 0) || 0;
     991  const items = [
     992    ...(posts || []).map((p) => buildCreate(base, site, p)),
     993    ...(tracks || []).map((r) => buildTrackCreate(base, site, r)),
     994  ]
     995    .sort((a, b) => wanneer(b) - wanneer(a))
     996    .slice(0, MAX_OUTBOX);
    950997  return {
    951998    '@context': AP_CONTEXT,
     
    59696016  buildActor, buildNote, buildCreate, buildOutbox, buildFollowers, buildFollowing, buildFeatured,
    59706017  channelUrls, timelineFields, guessMediaType,
    5971   siteOpenTracks, openTrack, buildTrackAudio, buildTrackCollection,
     6018  siteOpenTracks, openTrack, buildTrackAudio, buildTrackCollection, buildTrackCreate,
    59726019  buildPlaylistCollection, playlistOpenTracks, listPlaylistsAP, playlistLinkTags,
    59736020  followerCount, deliver, fetchActor, verifyRequest, handleInbox, deliverCreate, deliverDelete, deliverUpdate, deliverActorUpdate, resyncFeaturedPins,
Note: See TracChangeset for help on using the changeset viewer.