Changeset 952baf3 in Klonkt for src/routes/activitypub.js
- Timestamp:
- 08/07/2026 05:15:52 PM (5 weeks ago)
- Branches:
- main
- Children:
- ba76bf5
- Parents:
- f85b2c3 (diff), 0d5bd2c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
-
- 1 edited
-
src/routes/activitypub.js (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/activitypub.js
rf85b2c3 r952baf3 253 253 } 254 254 queueRoute('offers', (id, slug, me) => Guardianship.offersCollection(id, slug, me)); 255 queueRoute('follows', (id ) => Guardianship.followsCollection(id));255 queueRoute('follows', (id, slug, me) => Guardianship.followsCollection(id, slug, me)); 256 256 // §5.3 turned around (shaer-p729): what this ward has asked to follow, still 257 257 // waiting on its guardians. Owner-only like the rest — who a child wants to … … 268 268 // they follow) as Create(Note) items, so an app (Shaer) can build a unified 269 269 // feed. Anyone else gets 403; the inbox stays write-only for the public. 270 router.get('/ap/users/:slug/inbox', (req, res) => {270 router.get('/ap/users/:slug/inbox', async (req, res) => { 271 271 const auth = OAuth.verifyBearer(req.headers.authorization); 272 272 if (!auth || auth.site.slug !== req.params.slug) return res.status(403).end(); 273 273 const base = baseUrl(req); 274 // Wachten is een UITBREIDING van deze lezing, geen tweede endpoint (shaer-n05). 275 // Geef `since` (de shaer:cursor van je vorige antwoord) en `wait` mee, en het 276 // antwoord blijft hangen tot er iets is of de tijd om is. Zonder die twee 277 // gedraagt de route zich exact zoals altijd. 278 // 279 // Bewust hetzelfde antwoord in plaats van een "er is nieuws"-seintje: dan 280 // hoeft er niets nieuws geparsed te worden, is er geen tweede beschrijving van 281 // de kaartvorm die uit de pas kan lopen, en scheelt het de client een tweede 282 // ronde. 283 const wachtS = Math.min(Math.max(parseInt(req.query.wait, 10) || 0, 0), 50); 284 if (req.query.since && wachtS > 0) { 285 const afbreken = new AbortController(); 286 res.on('close', () => afbreken.abort()); // client hing op: niet doorgaan met wachten 287 const uit = await AP.waitForFeedChange(auth.site.slug, { 288 since: String(req.query.since), waitMs: wachtS * 1000, signal: afbreken.signal, 289 }); 290 if (res.writableEnded || afbreken.signal.aborted) return undefined; 291 // Niets veranderd? Dan een LEEG antwoord (Barts punt): de hele collectie 292 // terugsturen terwijl er niets gebeurd is, is elke 25 seconden een tijdlijn 293 // over de mobiele verbinding voor niets. Met 304 kost stilte niets en kost 294 // nieuws nog steeds maar één rondje -- beter dan een apart seintje-endpoint, 295 // dat voor nieuws twee rondjes nodig heeft. 296 // 297 // De '0'-uitzondering is geen franje. Ontbreekt ap_feed_state (een instance 298 // die de migratie nog niet draaide), dan geeft feedCursor altijd '0' terug, 299 // en zou een client hier eeuwig 304 krijgen en nooit meer inhoud zien. Bij 300 // een lege merksteen sturen we dus gewoon de collectie. 301 if (!uit.changed && uit.cursor !== '0') { 302 res.set('Vary', 'Authorization'); 303 return res.status(304).end(); 304 } 305 } 274 306 // Gated feature (FEP-633c): may this account see EXTERNAL embeds? A ward's 275 307 // world outside the fediverse is the guardians' call. The gate is applied … … 285 317 const playbackAllowed = embedsAllowed 286 318 && Guardianship.externalPlaybackAllowed(auth.site.external_playback, isWard); 287 const posts = AP.getTimeline(auth.site.slug, 60).map((t) => ({ 319 const rows = AP.getTimeline(auth.site.slug, 60); 320 // Eén query voor de hele pagina (shaer-9e9 fase 2): shaer:liked komt uit de 321 // tussentabel, de bron van waarheid, en niet meer uit de afgeleide kolom op 322 // ap_timeline. Per rij vragen zou hier een N+1 opleveren. 323 const reacties = AP.getReactionsFor(auth.site.slug, rows.map((t) => t.id)); 324 const posts = rows.map((t) => ({ 288 325 id: `${t.id}#create`, 289 326 type: 'Create', … … 333 370 // Whether THIS account already liked/boosted the note, so the app's 334 371 // detail-view buttons show the current state (and can toggle/undo). 335 'shaer:liked': !! t.liked,336 'shaer:boosted': !! t.boosted,372 'shaer:liked': !!(reacties.get(t.id) || {}).liked, 373 'shaer:boosted': !!(reacties.get(t.id) || {}).boosted, 337 374 // An external (non-fediverse) embed, thumbnail-only and never an iframe. 338 375 // Omitted entirely when the gate is closed (see above). … … 439 476 'shaer:externalLinks': playbackAllowed, 440 477 }, 478 // Het merk van wat hierin zit. Geef hem terug als `since` om op het 479 // volgende te wachten. NA het samenstellen bepaald, zodat hij precies dekt 480 // wat je in handen hebt en niet iets dat er ondertussen bij kwam. 481 'shaer:cursor': AP.feedCursor(auth.site.slug), 441 482 totalItems: items.length, 442 483 orderedItems: items, 443 484 }); 485 return undefined; 444 486 }); 445 487
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)