Ignore:
Timestamp:
08/10/2026 03:32:22 PM (4 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
41de7cb
Parents:
3bbf73d
Message:

De wachtende lezing antwoordt met het verschil, als je erom vraagt

shaer-pq4, tweede helft van stap 1. Samentrekken van de twee waiters bespaart
het RONDJE; dit bespaart de VRACHT. Beide paden eindigden tot nu toe in een
volledige inboxlezing -- vier legs van zestig met al hun media-, quote- en
embed-JSON -- voor een enkel nieuw bericht.

Het verschil lag al klaar en werd nooit uitgedeeld: ap_feed_state houdt per
object bij wat er wanneer veranderde, en feedChangesSince had geen enkele
aanroeper. Nu wel, achter ?changes=1.

OPT-IN, en dat is geen franje: een app in het veld stuurt since al mee en
vervangt haar hele feed door wat er terugkomt. Zou since opeens een verschil
betekenen, dan wist die app zichzelf leeg. Een toets bewaakt dat de oude lezing
zonder changes=1 exact hetzelfde blijft.

Het antwoord is een OrderedCollectionPage met partOf, want dat is wat het IS.
Een generieke lezer ziet dat verschil ook.

GRAFSTENEN GAAN MEE. Een verwijdering reisde tot nu toe als AFWEZIGHEID: de
volledige lezing bevatte hem simpelweg niet meer. Juist die volledigheid valt
hier weg, dus zonder Tombstone zou een weggehaalde post voor altijd in de app
blijven staan -- en dat faalt stil. Bart noemde de voorwaarde terecht niet
hard, maar de rijen lagen er al (kind='deleted') en AS2 heeft er een vorm voor.

Om de kaartvorm niet twee keer te beschrijven zijn ook de tijdlijn- en
antwoordvorm uit de handler gehesen (timelineItem/replyItem), net als eerder
messageItem/sentItem. Zelfde gedrag, 855/855 groen.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/services/ActivityPubService.js

    r3bbf73d rf0a33e1  
    40954095// everywhere EXCEPT in the other's app (Robins melding, 30-7: "komt niet
    40964096// binnen bij de ander").
     4097const REPLY_COLUMNS = `
     4098      i.object_uri, i.actor_uri, i.actor_name, i.actor_handle, i.actor_icon, i.actor_url,
     4099      i.content, i.published, i.created_at, i.parent_uri, i.post_id,
     4100      i.emoji_json, i.actor_emoji_json, i.media_json, i.quote_json, i.embed_json`;
     4101
     4102/** Dezelfde antwoordrijen, maar op object-uri -- voor de verschil-lezing. */
     4103export function replyRowsByUri(slug, uris) {
     4104  const list = (uris || []).filter((u) => typeof u === 'string' && u);
     4105  if (!list.length) return [];
     4106  try {
     4107    const holes = list.map(() => '?').join(',');
     4108    return db.prepare(`SELECT ${REPLY_COLUMNS} FROM ap_interactions i
     4109                        JOIN posts p ON p.id = i.post_id
     4110                        JOIN sites s ON s.id = p.site_id
     4111                       WHERE s.slug = ? AND i.kind = 'reply' AND i.object_uri IN (${holes})`)
     4112      .all(slug, ...list);
     4113  } catch { return []; }
     4114}
     4115
     4116/** Tijdlijnrijen op id, met dezelfde afgeleide liked/boosted als getTimeline. */
     4117export function timelineRowsByIds(slug, ids) {
     4118  const list = (ids || []).filter((u) => typeof u === 'string' && u);
     4119  if (!list.length) return [];
     4120  try {
     4121    const holes = list.map(() => '?').join(',');
     4122    const rows = db.prepare(`SELECT * FROM ap_timeline WHERE slug = ? AND id IN (${holes})`).all(slug, ...list);
     4123    const reacties = getReactionsFor(slug, rows.map((r) => r.id));
     4124    for (const r of rows) {
     4125      const x = reacties.get(r.id);
     4126      r.liked = !!(x && x.liked);
     4127      r.boosted = !!(x && x.boosted);
     4128    }
     4129    return rows;
     4130  } catch { return []; }
     4131}
     4132
    40974133export function getReplyMessages(slug, limit) {
    40984134  try {
    40994135    return db.prepare(`
    4100       SELECT i.object_uri, i.actor_uri, i.actor_name, i.actor_handle, i.actor_icon, i.actor_url,
    4101              i.content, i.published, i.created_at, i.parent_uri, i.post_id,
    4102              i.emoji_json, i.actor_emoji_json, i.media_json, i.quote_json, i.embed_json
     4136      SELECT ${REPLY_COLUMNS}
    41034137      FROM ap_interactions i
    41044138      JOIN posts p ON p.id = i.post_id
     
    63916425  getInteractions, getInteractionById, setInteractionBoosted, setInteractionLiked, buildReplyNote, getOutboxNote, getSentNotes, deliverReply, resolveRemoteNote, noteAudience, mayReadNote,
    63926426  listOutbox, deliverOutboxDelete, deliverOutboxUpdate, deliverDirectNote,
    6393   webfingerResolve, followActor, resolveRemoteActor, unfollowActor, handleMoveInbox, moveAccount, listFollowing, setAutoBoost, backfillFromOutbox, getTimeline, getDirectMessages, messageRowsByUri, conversationHeads, conversationHistory, isoStamp, timelineAttachments, timelineEmojis, timelineObjectLinks, timelineQuote, timelineEmbed, applyQuoteProps, deliverToActor, sendInteraction, voteOnPoll, voteOnRemotePoll,
     6427  webfingerResolve, followActor, resolveRemoteActor, unfollowActor, handleMoveInbox, moveAccount, listFollowing, setAutoBoost, backfillFromOutbox, getTimeline, timelineRowsByIds, getDirectMessages, messageRowsByUri, replyRowsByUri, conversationHeads, conversationHistory, isoStamp, timelineAttachments, timelineEmojis, timelineObjectLinks, timelineQuote, timelineEmbed, applyQuoteProps, deliverToActor, sendInteraction, voteOnPoll, voteOnRemotePoll,
    63946428  acceptGatedFollow, rejectGatedFollow, isWardGuardian, outboxAudience, sendFollowDecision,
    63956429  gateOutgoingFollow, performApprovedFollow, recordGuardianEvent, listGuardianEvents, GUARDIAN_EVENT_KEEP,
Note: See TracChangeset for help on using the changeset viewer.