Changeset af21002 in Klonkt


Ignore:
Timestamp:
07/16/2026 12:20:51 PM (8 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
476d6e7
Parents:
2d6a9c3
git-author:
Robin <roboburr@…> (07/13/2026 05:24:58 AM)
git-committer:
Robin <roboburr@…> (07/16/2026 12:20:51 PM)
Message:

Spoor A step 2: resolve @mentions into the baked content at save

bakePostContentWithMentions() runs the same webfinger resolver the federated
copy uses, ONCE at save, and bakes @user@host profile links into
content_rendered — so the site shows clickable mentions with no per-view
lookup. cacheRenderedContent stores the sync #tag/URL bake immediately, then
re-stores with mentions resolved asynchronously, so a slow/dead remote server
never blocks the save. Unresolvable handles stay plain text; any failure keeps
the sync bake. Verified: no-mention content unchanged, dead handle degrades
gracefully, and a live @Gargron@… resolves to a profile link.

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

Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/routes/posts.js

    r2d6a9c3 raf21002  
    243243// baking on the fly if this ever fails.
    244244function cacheRenderedContent(postId, rawContent) {
     245  const raw = rawContent || '';
     246  // 1. Immediate + synchronous: bake #hashtags + URLs so the post renders enriched at once.
    245247  try {
    246248    db.prepare('UPDATE posts SET content_rendered = ? WHERE id = ?')
    247       .run(ActivityPubService.bakePostContent(rawContent || ''), postId);
     249      .run(ActivityPubService.bakePostContent(raw), postId);
    248250  } catch (e) { /* fallback bake in the render route keeps display correct */ }
     251  // 2. Async: resolve @mentions (webfinger, once) and re-store, WITHOUT blocking the save
     252  //    response — a moment later the post's @mentions are clickable too. A slow/dead remote
     253  //    server can't stall the save; on failure the sync bake from step 1 stands.
     254  ActivityPubService.bakePostContentWithMentions(raw)
     255    .then((html) => {
     256      try { db.prepare('UPDATE posts SET content_rendered = ? WHERE id = ?').run(html, postId); }
     257      catch (e) { /* keep the sync bake */ }
     258    })
     259    .catch(() => { /* keep the sync bake */ });
    249260}
    250261
  • src/services/ActivityPubService.js

    r2d6a9c3 raf21002  
    14721472}
    14731473
     1474// Step 2: the full bake, incl. @mention links. Resolves @user@host via webfinger ONCE (the
     1475// same resolver the federated copy uses) and bakes the profile links into content_rendered,
     1476// so page views never do a per-view lookup. Unresolvable handles stay plain text; on any
     1477// failure it degrades to the sync #hashtag/URL bake. Async (webfinger) → callers run it off
     1478// the save response so the request never blocks on a slow/dead remote server.
     1479export async function bakePostContentWithMentions(source) {
     1480  const withHashUrls = bakePostContent(source);
     1481  try { const m = await resolveMentionsInText('', withHashUrls); return m.html; }
     1482  catch { return withHashUrls; }
     1483}
     1484
    14741485// Extract the AP Hashtag tag objects from already-linked reply content.
    14751486function hashtagTags(base, content) {
     
    24712482  deliverWithRetry, enqueueDelivery, processDeliveryQueue, startDeliveryWorker,
    24722483  getReplyUris, markNotificationsSeen, countUnseenNotifications, hasPlayableAudio,
    2473   linkifyBody, bakePostContent, listFollowers, removeFollower,
     2484  linkifyBody, bakePostContent, bakePostContentWithMentions, listFollowers, removeFollower,
    24742485};
Note: See TracChangeset for help on using the changeset viewer.