@atproto/bsky 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/dist/api/app/bsky/actor/getProfile.js +1 -1
- package/dist/api/app/bsky/actor/getProfile.js.map +1 -1
- package/dist/api/app/bsky/actor/getProfiles.js +1 -1
- package/dist/api/app/bsky/actor/getProfiles.js.map +1 -1
- package/dist/api/app/bsky/actor/getSuggestions.js +2 -2
- package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
- package/dist/api/app/bsky/embed/getEmbedExternalView.d.ts.map +1 -1
- package/dist/api/app/bsky/embed/getEmbedExternalView.js +132 -53
- package/dist/api/app/bsky/embed/getEmbedExternalView.js.map +1 -1
- package/dist/api/app/bsky/feed/getAuthorFeed.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getAuthorFeed.js +4 -2
- package/dist/api/app/bsky/feed/getAuthorFeed.js.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +2 -2
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
- package/dist/api/app/bsky/notification/constants.d.ts +4 -1
- package/dist/api/app/bsky/notification/constants.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/constants.js +3 -0
- package/dist/api/app/bsky/notification/constants.js.map +1 -1
- package/dist/api/app/bsky/notification/getGroupedNotifications.js +19 -7
- package/dist/api/app/bsky/notification/getGroupedNotifications.js.map +1 -1
- package/dist/api/app/bsky/notification/grouping/spotlight.d.ts +1 -1
- package/dist/api/app/bsky/notification/grouping/spotlight.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/grouping/spotlight.js +114 -80
- package/dist/api/app/bsky/notification/grouping/spotlight.js.map +1 -1
- package/dist/api/app/bsky/notification/listActivitySubscriptions.js +3 -2
- package/dist/api/app/bsky/notification/listActivitySubscriptions.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.d.ts +4 -0
- package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.js +142 -0
- package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.js.map +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/bsky/actor/getProfiles.js +4 -1
- package/dist/api/internal/bsky/actor/getProfiles.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -1
- package/dist/data-plane/server/indexing/index.d.ts +3 -1
- package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
- package/dist/data-plane/server/indexing/index.js +2 -0
- package/dist/data-plane/server/indexing/index.js.map +1 -1
- package/dist/data-plane/server/indexing/plugins/profile-link.d.ts +8 -0
- package/dist/data-plane/server/indexing/plugins/profile-link.d.ts.map +1 -0
- package/dist/data-plane/server/indexing/plugins/profile-link.js +30 -0
- package/dist/data-plane/server/indexing/plugins/profile-link.js.map +1 -0
- package/dist/data-plane/server/routes/records.d.ts.map +1 -1
- package/dist/data-plane/server/routes/records.js +1 -0
- package/dist/data-plane/server/routes/records.js.map +1 -1
- package/dist/hydration/actor.d.ts +4 -1
- package/dist/hydration/actor.d.ts.map +1 -1
- package/dist/hydration/actor.js +11 -0
- package/dist/hydration/actor.js.map +1 -1
- package/dist/hydration/external.d.ts +74 -70
- package/dist/hydration/external.d.ts.map +1 -1
- package/dist/hydration/external.js +79 -133
- package/dist/hydration/external.js.map +1 -1
- package/dist/hydration/hydrator.d.ts +57 -14
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +417 -105
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/lexicons/app/bsky/actor/defs.defs.d.ts +24 -0
- package/dist/lexicons/app/bsky/actor/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/actor/defs.defs.js +13 -0
- package/dist/lexicons/app/bsky/actor/defs.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/actor/link.d.ts +3 -0
- package/dist/lexicons/app/bsky/actor/link.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/actor/link.defs.d.ts +105 -0
- package/dist/lexicons/app/bsky/actor/link.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/actor/link.defs.js +34 -0
- package/dist/lexicons/app/bsky/actor/link.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/actor/link.js +6 -0
- package/dist/lexicons/app/bsky/actor/link.js.map +1 -0
- package/dist/lexicons/app/bsky/actor/profile.defs.d.ts +14 -0
- package/dist/lexicons/app/bsky/actor/profile.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/actor/profile.defs.js +3 -0
- package/dist/lexicons/app/bsky/actor/profile.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/actor.d.ts +1 -0
- package/dist/lexicons/app/bsky/actor.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/actor.js +1 -0
- package/dist/lexicons/app/bsky/actor.js.map +1 -1
- package/dist/lexicons/app/bsky/authFullApp.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/authFullApp.defs.js +1 -0
- package/dist/lexicons/app/bsky/authFullApp.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/authManageProfile.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/authManageProfile.defs.js +1 -0
- package/dist/lexicons/app/bsky/authManageProfile.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/embed/external.defs.d.ts +130 -0
- package/dist/lexicons/app/bsky/embed/external.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/embed/external.defs.js +135 -0
- package/dist/lexicons/app/bsky/embed/external.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/embed/getEmbedExternalView.defs.d.ts +15 -3
- package/dist/lexicons/app/bsky/embed/getEmbedExternalView.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/embed/getEmbedExternalView.defs.js +18 -3
- package/dist/lexicons/app/bsky/embed/getEmbedExternalView.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/notification/getGroupedNotifications.defs.d.ts +62 -3
- package/dist/lexicons/app/bsky/notification/getGroupedNotifications.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/notification/getGroupedNotifications.defs.js +53 -2
- package/dist/lexicons/app/bsky/notification/getGroupedNotifications.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.d.ts +3 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.d.ts +103 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.d.ts.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.js +95 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.js +6 -0
- package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.js.map +1 -0
- package/dist/lexicons/app/bsky/unspecced.d.ts +1 -0
- package/dist/lexicons/app/bsky/unspecced.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced.js +1 -0
- package/dist/lexicons/app/bsky/unspecced.js.map +1 -1
- package/dist/lexicons/index.d.ts +2 -0
- package/dist/lexicons/index.d.ts.map +1 -1
- package/dist/lexicons/index.js +2 -0
- package/dist/lexicons/index.js.map +1 -1
- package/dist/lexicons/place/stream/badge/defs.d.ts +2 -0
- package/dist/lexicons/place/stream/badge/defs.d.ts.map +1 -0
- package/dist/lexicons/place/stream/badge/defs.defs.d.ts +131 -0
- package/dist/lexicons/place/stream/badge/defs.defs.d.ts.map +1 -0
- package/dist/lexicons/place/stream/badge/defs.defs.js +73 -0
- package/dist/lexicons/place/stream/badge/defs.defs.js.map +1 -0
- package/dist/lexicons/place/stream/badge/defs.js +5 -0
- package/dist/lexicons/place/stream/badge/defs.js.map +1 -0
- package/dist/lexicons/place/stream/badge.d.ts +2 -0
- package/dist/lexicons/place/stream/badge.d.ts.map +1 -0
- package/dist/lexicons/place/stream/badge.js +5 -0
- package/dist/lexicons/place/stream/badge.js.map +1 -0
- package/dist/lexicons/place/stream/chat/defs.d.ts +2 -0
- package/dist/lexicons/place/stream/chat/defs.d.ts.map +1 -0
- package/dist/lexicons/place/stream/chat/defs.defs.d.ts +44 -0
- package/dist/lexicons/place/stream/chat/defs.defs.d.ts.map +1 -0
- package/dist/lexicons/place/stream/chat/defs.defs.js +41 -0
- package/dist/lexicons/place/stream/chat/defs.defs.js.map +1 -0
- package/dist/lexicons/place/stream/chat/defs.js +5 -0
- package/dist/lexicons/place/stream/chat/defs.js.map +1 -0
- package/dist/lexicons/place/stream/chat/pinnedRecord.d.ts +3 -0
- package/dist/lexicons/place/stream/chat/pinnedRecord.d.ts.map +1 -0
- package/dist/lexicons/place/stream/chat/pinnedRecord.defs.d.ts +108 -0
- package/dist/lexicons/place/stream/chat/pinnedRecord.defs.d.ts.map +1 -0
- package/dist/lexicons/place/stream/chat/pinnedRecord.defs.js +31 -0
- package/dist/lexicons/place/stream/chat/pinnedRecord.defs.js.map +1 -0
- package/dist/lexicons/place/stream/chat/pinnedRecord.js +6 -0
- package/dist/lexicons/place/stream/chat/pinnedRecord.js.map +1 -0
- package/dist/lexicons/place/stream/chat/profile.d.ts +3 -0
- package/dist/lexicons/place/stream/chat/profile.d.ts.map +1 -0
- package/dist/lexicons/place/stream/chat/profile.defs.d.ts +143 -0
- package/dist/lexicons/place/stream/chat/profile.defs.d.ts.map +1 -0
- package/dist/lexicons/place/stream/chat/profile.defs.js +62 -0
- package/dist/lexicons/place/stream/chat/profile.defs.js.map +1 -0
- package/dist/lexicons/place/stream/chat/profile.js +6 -0
- package/dist/lexicons/place/stream/chat/profile.js.map +1 -0
- package/dist/lexicons/place/stream/chat.d.ts +4 -0
- package/dist/lexicons/place/stream/chat.d.ts.map +1 -0
- package/dist/lexicons/place/stream/chat.js +7 -0
- package/dist/lexicons/place/stream/chat.js.map +1 -0
- package/dist/lexicons/place/stream/defs.d.ts +2 -0
- package/dist/lexicons/place/stream/defs.d.ts.map +1 -0
- package/dist/lexicons/place/stream/defs.defs.d.ts +54 -0
- package/dist/lexicons/place/stream/defs.defs.d.ts.map +1 -0
- package/dist/lexicons/place/stream/defs.defs.js +40 -0
- package/dist/lexicons/place/stream/defs.defs.js.map +1 -0
- package/dist/lexicons/place/stream/defs.js +5 -0
- package/dist/lexicons/place/stream/defs.js.map +1 -0
- package/dist/lexicons/place/stream/livestream.d.ts +3 -0
- package/dist/lexicons/place/stream/livestream.d.ts.map +1 -0
- package/dist/lexicons/place/stream/livestream.defs.d.ts +312 -0
- package/dist/lexicons/place/stream/livestream.defs.d.ts.map +1 -0
- package/dist/lexicons/place/stream/livestream.defs.js +105 -0
- package/dist/lexicons/place/stream/livestream.defs.js.map +1 -0
- package/dist/lexicons/place/stream/livestream.js +6 -0
- package/dist/lexicons/place/stream/livestream.js.map +1 -0
- package/dist/lexicons/place/stream.d.ts +5 -0
- package/dist/lexicons/place/stream.d.ts.map +1 -0
- package/dist/lexicons/place/stream.js +8 -0
- package/dist/lexicons/place/stream.js.map +1 -0
- package/dist/lexicons/place.d.ts +2 -0
- package/dist/lexicons/place.d.ts.map +1 -0
- package/dist/lexicons/place.js +5 -0
- package/dist/lexicons/place.js.map +1 -0
- package/dist/lexicons/site/standard/document.defs.d.ts +127 -127
- package/dist/lexicons/site/standard/document.defs.d.ts.map +1 -1
- package/dist/lexicons/site/standard/document.defs.js +28 -28
- package/dist/lexicons/site/standard/document.defs.js.map +1 -1
- package/dist/lexicons/site/standard/graph/recommend.defs.d.ts +11 -11
- package/dist/lexicons/site/standard/graph/recommend.defs.d.ts.map +1 -1
- package/dist/lexicons/site/standard/graph/recommend.defs.js +1 -1
- package/dist/lexicons/site/standard/graph/recommend.defs.js.map +1 -1
- package/dist/lexicons/site/standard/publication.defs.d.ts +52 -52
- package/dist/lexicons/site/standard/publication.defs.d.ts.map +1 -1
- package/dist/lexicons/site/standard/publication.defs.js +6 -6
- package/dist/lexicons/site/standard/publication.defs.js.map +1 -1
- package/dist/lexicons/site/standard/theme/basic.defs.d.ts +14 -14
- package/dist/lexicons/site/standard/theme/basic.defs.d.ts.map +1 -1
- package/dist/lexicons/site/standard/theme/basic.defs.js +1 -1
- package/dist/lexicons/site/standard/theme/basic.defs.js.map +1 -1
- package/dist/lexicons/social/grain/defs.d.ts +2 -0
- package/dist/lexicons/social/grain/defs.d.ts.map +1 -0
- package/dist/lexicons/social/grain/defs.defs.d.ts +15 -0
- package/dist/lexicons/social/grain/defs.defs.d.ts.map +1 -0
- package/dist/lexicons/social/grain/defs.defs.js +14 -0
- package/dist/lexicons/social/grain/defs.defs.js.map +1 -0
- package/dist/lexicons/social/grain/defs.js +5 -0
- package/dist/lexicons/social/grain/defs.js.map +1 -0
- package/dist/lexicons/social/grain/favorite.d.ts +3 -0
- package/dist/lexicons/social/grain/favorite.d.ts.map +1 -0
- package/dist/lexicons/social/grain/favorite.defs.d.ts +72 -0
- package/dist/lexicons/social/grain/favorite.defs.d.ts.map +1 -0
- package/dist/lexicons/social/grain/favorite.defs.js +26 -0
- package/dist/lexicons/social/grain/favorite.defs.js.map +1 -0
- package/dist/lexicons/social/grain/favorite.js +6 -0
- package/dist/lexicons/social/grain/favorite.js.map +1 -0
- package/dist/lexicons/social/grain/gallery/item.d.ts +3 -0
- package/dist/lexicons/social/grain/gallery/item.d.ts.map +1 -0
- package/dist/lexicons/social/grain/gallery/item.defs.d.ts +94 -0
- package/dist/lexicons/social/grain/gallery/item.defs.d.ts.map +1 -0
- package/dist/lexicons/social/grain/gallery/item.defs.js +29 -0
- package/dist/lexicons/social/grain/gallery/item.defs.js.map +1 -0
- package/dist/lexicons/social/grain/gallery/item.js +6 -0
- package/dist/lexicons/social/grain/gallery/item.js.map +1 -0
- package/dist/lexicons/social/grain/gallery.d.ts +4 -0
- package/dist/lexicons/social/grain/gallery.d.ts.map +1 -0
- package/dist/lexicons/social/grain/gallery.defs.d.ts +98 -0
- package/dist/lexicons/social/grain/gallery.defs.d.ts.map +1 -0
- package/dist/lexicons/social/grain/gallery.defs.js +33 -0
- package/dist/lexicons/social/grain/gallery.defs.js.map +1 -0
- package/dist/lexicons/social/grain/gallery.js +7 -0
- package/dist/lexicons/social/grain/gallery.js.map +1 -0
- package/dist/lexicons/social/grain/photo.d.ts +3 -0
- package/dist/lexicons/social/grain/photo.d.ts.map +1 -0
- package/dist/lexicons/social/grain/photo.defs.d.ts +98 -0
- package/dist/lexicons/social/grain/photo.defs.d.ts.map +1 -0
- package/dist/lexicons/social/grain/photo.defs.js +31 -0
- package/dist/lexicons/social/grain/photo.defs.js.map +1 -0
- package/dist/lexicons/social/grain/photo.js +6 -0
- package/dist/lexicons/social/grain/photo.js.map +1 -0
- package/dist/lexicons/social/grain.d.ts +5 -0
- package/dist/lexicons/social/grain.d.ts.map +1 -0
- package/dist/lexicons/social/grain.js +8 -0
- package/dist/lexicons/social/grain.js.map +1 -0
- package/dist/lexicons/social.d.ts +2 -0
- package/dist/lexicons/social.d.ts.map +1 -0
- package/dist/lexicons/social.js +5 -0
- package/dist/lexicons/social.js.map +1 -0
- package/dist/proto/bsky_connect.d.ts +10 -1
- package/dist/proto/bsky_connect.d.ts.map +1 -1
- package/dist/proto/bsky_connect.js +10 -1
- package/dist/proto/bsky_connect.js.map +1 -1
- package/dist/proto/bsky_pb.d.ts +34 -0
- package/dist/proto/bsky_pb.d.ts.map +1 -1
- package/dist/proto/bsky_pb.js +60 -0
- package/dist/proto/bsky_pb.js.map +1 -1
- package/dist/telemetry/events.d.ts +30 -0
- package/dist/telemetry/events.d.ts.map +1 -1
- package/dist/telemetry/events.js +37 -0
- package/dist/telemetry/events.js.map +1 -1
- package/dist/util/external/index.d.ts +8 -0
- package/dist/util/external/index.d.ts.map +1 -0
- package/dist/util/external/index.js +50 -0
- package/dist/util/external/index.js.map +1 -0
- package/dist/util/{standard-site.d.ts → external/standard-site.d.ts} +30 -4
- package/dist/util/external/standard-site.d.ts.map +1 -0
- package/dist/util/{standard-site.js → external/standard-site.js} +73 -4
- package/dist/util/external/standard-site.js.map +1 -0
- package/dist/views/external.d.ts +8 -0
- package/dist/views/external.d.ts.map +1 -0
- package/dist/views/external.js +260 -0
- package/dist/views/external.js.map +1 -0
- package/dist/views/index.d.ts +12 -6
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +89 -42
- package/dist/views/index.js.map +1 -1
- package/dist/views/profile-link-rules.d.ts +10 -0
- package/dist/views/profile-link-rules.d.ts.map +1 -0
- package/dist/views/profile-link-rules.js +48 -0
- package/dist/views/profile-link-rules.js.map +1 -0
- package/dist/views/types.d.ts +3 -0
- package/dist/views/types.d.ts.map +1 -1
- package/dist/views/types.js.map +1 -1
- package/package.json +4 -4
- package/dist/util/standard-site.d.ts.map +0 -1
- package/dist/util/standard-site.js.map +0 -1
|
@@ -3,25 +3,15 @@ import { parseAtUriString } from '@atproto/syntax';
|
|
|
3
3
|
import { site } from '../lexicons/index.js';
|
|
4
4
|
import { hydrationLogger } from '../logger.js';
|
|
5
5
|
import { RecordLookupStatus, } from '../proto/bsky_pb.js';
|
|
6
|
+
import { events, } from '../telemetry/events.js';
|
|
7
|
+
import { uriToDid } from '../util/uris.js';
|
|
6
8
|
import { HydrationMap, parseDate, safeTakedownRef, } from './util.js';
|
|
7
|
-
/**
|
|
8
|
-
* Composes a stable map key from an `(uri, cid)` pair. A single hydration
|
|
9
|
-
* batch can pull more than one version of the same record URI (different
|
|
10
|
-
* posts pinning different cids), so the composite is needed for O(1)
|
|
11
|
-
* version-exact lookups.
|
|
12
|
-
*/
|
|
13
|
-
export function genericRecordKey(uri, cid) {
|
|
14
|
-
return `${uri}@${cid}`;
|
|
15
|
-
}
|
|
16
|
-
/** Recover the URI and CID from a composite hydration key. */
|
|
17
|
-
export function parseGenericRecordKey(key) {
|
|
18
|
-
const at = key.lastIndexOf('@');
|
|
19
|
-
return {
|
|
20
|
-
uri: key.slice(0, at),
|
|
21
|
-
cid: key.slice(at + 1),
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
9
|
export class ExternalHydrator {
|
|
10
|
+
static { this.MAX_BACKLINK_PREVIEWS = 3; }
|
|
11
|
+
static { this.MAX_BACKLINK_GALLERY_ITEMS = 10; }
|
|
12
|
+
static { this.MAX_BACKLINK_FANOUT = 8; }
|
|
13
|
+
/** Hard cap on generic batches per traversal, counting the root as pass 1. */
|
|
14
|
+
static { this.MAX_EXTERNAL_HYDRATION_PASSES = 8; }
|
|
25
15
|
constructor(dataplane) {
|
|
26
16
|
this.dataplane = dataplane;
|
|
27
17
|
}
|
|
@@ -32,8 +22,7 @@ export class ExternalHydrator {
|
|
|
32
22
|
return map;
|
|
33
23
|
const res = await this.dataplane.getRecordsByRef({ refs });
|
|
34
24
|
for (let i = 0; i < refs.length; i++) {
|
|
35
|
-
|
|
36
|
-
map.set(genericRecordKey(uri, cid), parseGenericRecord(res.results[i], includeTakedowns) ?? null);
|
|
25
|
+
map.set(genericRecordKey(refs[i]), parseGenericRecord(res.results[i], includeTakedowns) ?? null);
|
|
37
26
|
}
|
|
38
27
|
return map;
|
|
39
28
|
}
|
|
@@ -124,38 +113,77 @@ export class ExternalHydrator {
|
|
|
124
113
|
}
|
|
125
114
|
return out;
|
|
126
115
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
116
|
+
}
|
|
117
|
+
export function genericRecordKey({ uri, cid }) {
|
|
118
|
+
if (cid === undefined)
|
|
119
|
+
return uri;
|
|
120
|
+
if (!cid)
|
|
121
|
+
throw new Error(`Empty CID in record key for ${uri}`);
|
|
122
|
+
return `${uri}@${cid}`;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Recover the URI and CID from an exact record key, splitting at the last `@`.
|
|
126
|
+
* Throws if either part is missing. Components are trusted, not revalidated.
|
|
127
|
+
*/
|
|
128
|
+
export function parseGenericRecordKey(key) {
|
|
129
|
+
const at = key.lastIndexOf('@');
|
|
130
|
+
if (at <= 0 || at === key.length - 1) {
|
|
131
|
+
throw new Error(`Malformed exact record key: ${key}`);
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
uri: key.slice(0, at),
|
|
135
|
+
cid: key.slice(at + 1),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Null generic external records (in both the URI-keyed and exact-ref maps,
|
|
140
|
+
* keeping their keys) that are taken down by an actionable label, unless
|
|
141
|
+
* takedowns are included, or whose owner is explicitly unavailable. Applies to
|
|
142
|
+
* each record independently; counts and other records are unaffected.
|
|
143
|
+
*/
|
|
144
|
+
export function actionExternalRecordTakedowns({ externalRecords, externalRecordsByRef, actors, labels, }, includeTakedowns) {
|
|
145
|
+
// An absent actor entry was not hydrated; only `null` means unavailable.
|
|
146
|
+
const isHidden = (uri) => actors?.get(uriToDid(uri)) === null ||
|
|
147
|
+
(!includeTakedowns && labels?.get(uri)?.isTakendown);
|
|
148
|
+
for (const [uri, info] of externalRecords ?? []) {
|
|
149
|
+
if (!info || !isHidden(uri))
|
|
150
|
+
continue;
|
|
151
|
+
externalRecords?.set(uri, null);
|
|
152
|
+
externalRecordsByRef?.set(genericRecordKey({ uri, cid: info.cid }), null);
|
|
153
|
+
}
|
|
154
|
+
// Every exact version is checked on its own; versions are never collapsed.
|
|
155
|
+
for (const [key, info] of externalRecordsByRef ?? []) {
|
|
156
|
+
if (info && isHidden(parseGenericRecordKey(key).uri)) {
|
|
157
|
+
externalRecordsByRef?.set(key, null);
|
|
149
158
|
}
|
|
150
|
-
return out;
|
|
151
159
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Run `fn` with the caller's tracker, or as the owner of a new traversal when
|
|
163
|
+
* there is none. Only the owner reports, once, including on failure. Owners
|
|
164
|
+
* that completed without scheduling a batch did no work and are not reported;
|
|
165
|
+
* caps and failures always are.
|
|
166
|
+
*/
|
|
167
|
+
export async function trackExternalHydration(root, hydrationMetrics, fn) {
|
|
168
|
+
if (hydrationMetrics)
|
|
169
|
+
return fn(hydrationMetrics);
|
|
170
|
+
const owned = { recordLookups: 0, batches: 0, maxPass: 0, capped: false };
|
|
171
|
+
let outcome = 'failed';
|
|
172
|
+
try {
|
|
173
|
+
const state = await fn(owned);
|
|
174
|
+
outcome = owned.capped ? 'capped' : 'completed';
|
|
175
|
+
return state;
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
if (owned.batches || outcome !== 'completed') {
|
|
179
|
+
const { recordLookups, batches, maxPass } = owned;
|
|
180
|
+
events.externalHydrationTraversal({
|
|
181
|
+
root,
|
|
182
|
+
outcome,
|
|
183
|
+
recordLookups,
|
|
184
|
+
batches,
|
|
185
|
+
maxPass,
|
|
186
|
+
});
|
|
159
187
|
}
|
|
160
188
|
}
|
|
161
189
|
}
|
|
@@ -203,14 +231,6 @@ const siteStandardKind = (uri) => {
|
|
|
203
231
|
return undefined;
|
|
204
232
|
}
|
|
205
233
|
};
|
|
206
|
-
/** The AT-URI of the publication a document's `site` field points at. */
|
|
207
|
-
const publicationUriFromSite = (value) => {
|
|
208
|
-
const parsed = parseAtUriString(value);
|
|
209
|
-
return parsed.success &&
|
|
210
|
-
parsed.value.collection === site.standard.publication.$type
|
|
211
|
-
? value
|
|
212
|
-
: undefined;
|
|
213
|
-
};
|
|
214
234
|
/**
|
|
215
235
|
* Generic record bodies are unvalidated, so check them against the Lexicon
|
|
216
236
|
* before exposing typed fields. Parse mode is not used, to preserve the
|
|
@@ -239,14 +259,6 @@ const setSiteStandardRecord = (out, uri, key, info) => {
|
|
|
239
259
|
* that doesn't structurally agree is rejected, so downstream callers can
|
|
240
260
|
* trust the returned shape.
|
|
241
261
|
*
|
|
242
|
-
* Same observable contract as
|
|
243
|
-
* `getSiteStandardRecordsFromHydrationMapsByDocumentUri` (the compose-path
|
|
244
|
-
* sister) — both functions guarantee that a returned `(doc, pub)` pair
|
|
245
|
-
* has matching site/uri, and reject orphan docs that claim a
|
|
246
|
-
* non-hydrated publication. They differ only in how upstream availability
|
|
247
|
-
* is asserted: this one trusts caller-supplied refs; the sister derives
|
|
248
|
-
* everything from the dataplane response.
|
|
249
|
-
*
|
|
250
262
|
* Pairing rules:
|
|
251
263
|
* - Both slots referenced: `doc.site` must equal `publication.ref.uri`,
|
|
252
264
|
* else both come back `undefined`.
|
|
@@ -268,7 +280,7 @@ export const getSiteStandardRecordsFromHydrationMapsByRefs = (associatedRefs, do
|
|
|
268
280
|
let document;
|
|
269
281
|
let publication;
|
|
270
282
|
for (const ref of associatedRefs) {
|
|
271
|
-
const key = genericRecordKey(ref
|
|
283
|
+
const key = genericRecordKey(ref);
|
|
272
284
|
if (!document) {
|
|
273
285
|
const hit = documents?.get(key);
|
|
274
286
|
if (hit)
|
|
@@ -296,8 +308,7 @@ export const getSiteStandardRecordsFromHydrationMapsByRefs = (associatedRefs, do
|
|
|
296
308
|
}
|
|
297
309
|
}
|
|
298
310
|
// Doc with at-uri `site` but no publication: the post should have
|
|
299
|
-
// pinned the publication too. Treat as misconstructed
|
|
300
|
-
// as the compose-path lookup.
|
|
311
|
+
// pinned the publication too. Treat as misconstructed.
|
|
301
312
|
if (document && !publication) {
|
|
302
313
|
const site = document.info.record.site;
|
|
303
314
|
if (site && site.startsWith('at://')) {
|
|
@@ -307,69 +318,4 @@ export const getSiteStandardRecordsFromHydrationMapsByRefs = (associatedRefs, do
|
|
|
307
318
|
}
|
|
308
319
|
return { document, publication };
|
|
309
320
|
};
|
|
310
|
-
/**
|
|
311
|
-
* Compose-path resolution: no caller-supplied refs — the dataplane
|
|
312
|
-
* returned the latest version of each record (including any
|
|
313
|
-
* publications it auto-resolved from a document's `site` field). Take
|
|
314
|
-
* the first hydrated document and pair it with the publication its
|
|
315
|
-
* `site` field points at.
|
|
316
|
-
*
|
|
317
|
-
* Same observable contract as
|
|
318
|
-
* `getSiteStandardRecordsFromHydrationMapsByRefs` (the read-path
|
|
319
|
-
* sister) — both functions guarantee that a returned `(doc, pub)` pair
|
|
320
|
-
* has matching site/uri, and reject orphan docs that claim a
|
|
321
|
-
* non-hydrated publication. They differ only in how upstream
|
|
322
|
-
* availability is asserted: this one walks whatever was returned by the
|
|
323
|
-
* dataplane; the sister checks against caller-supplied refs.
|
|
324
|
-
*
|
|
325
|
-
* Pairing rules:
|
|
326
|
-
* - Doc with at-uri `site`: must find a hydrated publication at that
|
|
327
|
-
* URI. If none was hydrated, the doc/publication chain is incomplete
|
|
328
|
-
* and the function returns `undefined` for both slots; the doc alone
|
|
329
|
-
* isn't useful without its source (can't verify the pub)
|
|
330
|
-
* - Doc with web-URL `site` (loose): no publication.
|
|
331
|
-
* - No doc hydrated: fall through to the first hydrated publication for
|
|
332
|
-
* the publication-only resolution flow.
|
|
333
|
-
*/
|
|
334
|
-
export const getSiteStandardRecordsFromHydrationMapsByDocumentUri = (documents, publications) => {
|
|
335
|
-
// First hydrated doc.
|
|
336
|
-
let document;
|
|
337
|
-
for (const [key, info] of documents ?? []) {
|
|
338
|
-
if (!info)
|
|
339
|
-
continue;
|
|
340
|
-
document = { ref: parseGenericRecordKey(key), info };
|
|
341
|
-
break;
|
|
342
|
-
}
|
|
343
|
-
let publication;
|
|
344
|
-
if (document) {
|
|
345
|
-
const site = document.info.record.site;
|
|
346
|
-
if (site && site.startsWith('at://')) {
|
|
347
|
-
// Doc declared an at-uri publication; we need it.
|
|
348
|
-
for (const [key, info] of publications ?? []) {
|
|
349
|
-
if (!info)
|
|
350
|
-
continue;
|
|
351
|
-
const ref = parseGenericRecordKey(key);
|
|
352
|
-
if (ref.uri === site) {
|
|
353
|
-
publication = { ref, info };
|
|
354
|
-
break;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
if (!publication) {
|
|
358
|
-
hydrationLogger.warn({ documentUri: document.ref.uri, documentSite: site }, 'site.standard byDocumentUri lookup failed: document.site is AT URI but no matching publication was hydrated');
|
|
359
|
-
return { document: undefined, publication: undefined };
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
// else: loose doc (web-URL site), no publication needed.
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
// Publication-only flow: no doc, take the first hydrated publication.
|
|
366
|
-
for (const [key, info] of publications ?? []) {
|
|
367
|
-
if (!info)
|
|
368
|
-
continue;
|
|
369
|
-
publication = { ref: parseGenericRecordKey(key), info };
|
|
370
|
-
break;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
return { document, publication };
|
|
374
|
-
};
|
|
375
321
|
//# sourceMappingURL=external.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external.js","sourceRoot":"","sources":["../../src/hydration/external.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AtUriString,\n type DidString,\n type InferInput,\n type NsidString,\n type RecordSchema,\n type TypedLexMap,\n isTypedLexMap,\n lexParseJsonBytes,\n} from '@atproto/lex'\nimport { parseAtUriString } from '@atproto/syntax'\nimport type { DataPlaneClient } from '../data-plane/client/index.js'\nimport { site } from '../lexicons/index.js'\nimport { hydrationLogger } from '../logger.js'\nimport {\n type RecordLookupResult,\n RecordLookupStatus,\n} from '../proto/bsky_pb.js'\nimport type {\n SiteStandardDocumentRecord,\n SiteStandardPublicationRecord,\n} from '../views/types.js'\nimport {\n HydrationMap,\n type ItemRef,\n type RecordInfo,\n parseDate,\n safeTakedownRef,\n} from './util.js'\n\n/** Generic record bodies are decoded, but not validated against a Lexicon. */\nexport type GenericRecord = RecordInfo<TypedLexMap>\nexport type GenericRecords = HydrationMap<AtUriString, GenericRecord>\n/** Keyed by `genericRecordKey(uri, cid)` to retain multiple versions of a URI. */\nexport type GenericRecordsByRef = HydrationMap<string, GenericRecord>\n\nexport type AtmosphereActivityItem = {\n uri: AtUriString\n sortedAt: Date\n}\n\nexport type AtmosphereTimeline = {\n items: AtmosphereActivityItem[]\n cursor?: string\n}\n\nexport type AtmosphereBacklinks = {\n backlinks: AtmosphereActivityItem[]\n cursor?: string\n}\n\nexport type AtmosphereBacklinkCounts = HydrationMap<\n AtUriString,\n Partial<Record<NsidString, number>>\n>\n\nexport type AtmosphereBacklinksByActor = {\n backlinks: HydrationMap<AtUriString, AtUriString[]>\n truncated: boolean\n}\n\n/**\n * Composes a stable map key from an `(uri, cid)` pair. A single hydration\n * batch can pull more than one version of the same record URI (different\n * posts pinning different cids), so the composite is needed for O(1)\n * version-exact lookups.\n */\nexport function genericRecordKey(uri: AtUriString, cid: string): string {\n return `${uri}@${cid}`\n}\n\n/** Recover the URI and CID from a composite hydration key. */\nexport function parseGenericRecordKey(key: string): {\n uri: AtUriString\n cid: string\n} {\n const at = key.lastIndexOf('@')\n return {\n uri: key.slice(0, at) as AtUriString,\n cid: key.slice(at + 1),\n }\n}\n\nexport type SiteStandardDocument = RecordInfo<SiteStandardDocumentRecord>\nexport type SiteStandardPublication = RecordInfo<SiteStandardPublicationRecord>\n\n/**\n * Keyed by `${uri}@${cid}` — see `genericRecordKey`. A single hydration\n * batch can pull more than one version of the same URI (different posts\n * pinning different cids), so the composite key is needed for O(1)\n * version-exact lookups.\n */\nexport type SiteStandardDocuments = HydrationMap<string, SiteStandardDocument>\n/**\n * Keyed by `${uri}@${cid}`. See `SiteStandardDocuments` for the rationale.\n */\nexport type SiteStandardPublications = HydrationMap<\n string,\n SiteStandardPublication\n>\nexport type SiteStandardRecords = {\n documents: SiteStandardDocuments\n publications: SiteStandardPublications\n}\n\nexport type AssociatedSiteStandardRecord<T> = {\n ref: { uri: AtUriString; cid: string }\n info: T\n}\n\nexport class ExternalHydrator {\n constructor(public dataplane: DataPlaneClient) {}\n\n /** Fetch exact record versions; unavailable records are represented by null. */\n async getRecordsByRef(\n refs: Required<ItemRef>[],\n includeTakedowns = false,\n ): Promise<GenericRecordsByRef> {\n const map: GenericRecordsByRef = new HydrationMap()\n if (!refs.length) return map\n\n const res = await this.dataplane.getRecordsByRef({ refs })\n for (let i = 0; i < refs.length; i++) {\n const { uri, cid } = refs[i]\n map.set(\n genericRecordKey(uri, cid),\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\n }\n return map\n }\n\n /** Fetch the latest indexed versions without collection-specific validation. */\n async getRecordsByURI(\n uris: AtUriString[],\n includeTakedowns = false,\n ): Promise<GenericRecords> {\n const map: GenericRecords = new HydrationMap()\n if (!uris.length) return map\n\n const res = await this.dataplane.getRecordsByURI({ uris })\n for (let i = 0; i < uris.length; i++) {\n map.set(\n uris[i],\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\n }\n return map\n }\n\n /** Fetch a page of activity refs for subsequent generic record hydration. */\n async getAtmosphereTimeline(\n viewerDid: DidString,\n opts: { limit?: number; cursor?: string } = {},\n ): Promise<AtmosphereTimeline> {\n const res = await this.dataplane.getAtmosphereTimeline({\n viewerDid,\n ...opts,\n })\n return {\n items: res.items.map((item) => ({\n uri: item.uri as AtUriString,\n sortedAt: parseDate(item.sortedAt) ?? new Date(0),\n })),\n cursor: res.cursor || undefined,\n }\n }\n\n /** Fetch source-record counts, optionally restricted to one collection. */\n async getAtmosphereBacklinkCounts(\n targetUris: AtUriString[],\n collection?: NsidString,\n ): Promise<AtmosphereBacklinkCounts> {\n const map: AtmosphereBacklinkCounts = new HydrationMap()\n if (!targetUris.length) return map\n\n const res = await this.dataplane.getAtmosphereBacklinkCounts({\n targetUris,\n collection,\n })\n for (const result of res.results) {\n map.set(\n result.targetUri as AtUriString,\n Object.fromEntries(\n Object.entries(result.counts).map(([nsid, count]) => [\n nsid,\n Number(count),\n ]),\n ),\n )\n }\n return map\n }\n\n /** Fetch a page of source records linking to a target. */\n async getAtmosphereBacklinks(\n targetUri: AtUriString,\n collection: NsidString,\n opts: { limit?: number; cursor?: string } = {},\n ): Promise<AtmosphereBacklinks> {\n const res = await this.dataplane.getAtmosphereBacklinks({\n targetUri,\n collection,\n ...opts,\n })\n return {\n backlinks: res.backlinks.map((backlink) => ({\n uri: backlink.uri as AtUriString,\n sortedAt: parseDate(backlink.sortedAt) ?? new Date(0),\n })),\n cursor: res.cursor || undefined,\n }\n }\n\n /** Fetch an actor's links per target, retaining the batch truncation flag. */\n async getAtmosphereBacklinksByActor(\n targetUris: AtUriString[],\n actorDid: DidString,\n collection: NsidString,\n ): Promise<AtmosphereBacklinksByActor> {\n const backlinks: AtmosphereBacklinksByActor['backlinks'] =\n new HydrationMap()\n if (!targetUris.length) return { backlinks, truncated: false }\n\n const res = await this.dataplane.getAtmosphereBacklinksByActor({\n targetUris,\n actorDid,\n collection,\n })\n for (const result of res.results) {\n backlinks.set(\n result.targetUri as AtUriString,\n result.uris as AtUriString[],\n )\n }\n return { backlinks, truncated: res.truncated }\n }\n\n /**\n * Fetch exact `site.standard.{document,publication}` versions. Does NOT\n * resolve a document's publication; callers must pin it explicitly.\n */\n async getSiteStandardRecordsByRef(\n refs: ItemRef[],\n includeTakedowns = false,\n ): Promise<SiteStandardRecords> {\n const ssRefs = refs.filter(\n (ref): ref is Required<ItemRef> =>\n !!ref.cid && siteStandardKind(ref.uri) !== undefined,\n )\n const out = emptySiteStandardRecords()\n if (!ssRefs.length) return out\n\n const records = await this.getRecordsByRef(ssRefs, includeTakedowns)\n for (const [key, info] of records) {\n setSiteStandardRecord(out, parseGenericRecordKey(key).uri, key, info)\n }\n return out\n }\n\n /**\n * Fetch the latest `site.standard.{document,publication}` versions. The\n * generic record lookup does not follow references, so publications named\n * by the `site` field of the hydrated documents are fetched in a second\n * call.\n */\n async getSiteStandardRecordsByURI(\n uris: AtUriString[],\n includeTakedowns = false,\n ): Promise<SiteStandardRecords> {\n const requested = [...new Set(uris.filter((u) => siteStandardKind(u)))]\n const out = emptySiteStandardRecords()\n if (!requested.length) return out\n\n await this.addSiteStandardRecordsByURI(out, requested, includeTakedowns)\n\n // Publications referenced by documents but not already requested.\n const requestedSet = new Set<string>(requested)\n const pubUris = new Set<AtUriString>()\n for (const doc of out.documents.values()) {\n const pubUri = doc && publicationUriFromSite(doc.record.site)\n if (pubUri && !requestedSet.has(pubUri)) pubUris.add(pubUri)\n }\n if (pubUris.size) {\n await this.addSiteStandardRecordsByURI(\n out,\n [...pubUris],\n includeTakedowns,\n )\n }\n return out\n }\n\n private async addSiteStandardRecordsByURI(\n out: SiteStandardRecords,\n uris: AtUriString[],\n includeTakedowns: boolean,\n ) {\n const records = await this.getRecordsByURI(uris, includeTakedowns)\n for (const [uri, info] of records) {\n // Unavailable records have no CID to key on, so they are left out.\n if (!info) continue\n setSiteStandardRecord(out, uri, genericRecordKey(uri, info.cid), info)\n }\n }\n}\n\nfunction parseGenericRecord(\n result: RecordLookupResult | undefined,\n includeTakedowns: boolean,\n): GenericRecord | undefined {\n if (\n result?.status !== RecordLookupStatus.FOUND &&\n !(includeTakedowns && result?.status === RecordLookupStatus.TAKEN_DOWN)\n ) {\n return undefined\n }\n const entry = result.record\n if (!entry?.cid || !entry.record.byteLength) return undefined\n if (!includeTakedowns && entry.takenDown) return undefined\n\n let record: ReturnType<typeof lexParseJsonBytes>\n try {\n record = lexParseJsonBytes(entry.record, { strict: false })\n } catch {\n return undefined\n }\n if (!isTypedLexMap(record)) return undefined\n\n return {\n record,\n cid: entry.cid,\n sortedAt: parseDate(entry.sortedAt) ?? new Date(0),\n indexedAt: parseDate(entry.indexedAt) ?? new Date(0),\n takedownRef: safeTakedownRef(entry),\n }\n}\n\nconst emptySiteStandardRecords = (): SiteStandardRecords => ({\n documents: new HydrationMap(),\n publications: new HydrationMap(),\n})\n\nconst siteStandardKind = (\n uri: string,\n): keyof SiteStandardRecords | undefined => {\n const parsed = parseAtUriString(uri)\n if (!parsed.success) return undefined\n switch (parsed.value.collection) {\n case site.standard.document.$type:\n return 'documents'\n case site.standard.publication.$type:\n return 'publications'\n default:\n return undefined\n }\n}\n\n/** The AT-URI of the publication a document's `site` field points at. */\nconst publicationUriFromSite = (value: string): AtUriString | undefined => {\n const parsed = parseAtUriString(value)\n return parsed.success &&\n parsed.value.collection === site.standard.publication.$type\n ? (value as AtUriString)\n : undefined\n}\n\n/**\n * Generic record bodies are unvalidated, so check them against the Lexicon\n * before exposing typed fields. Parse mode is not used, to preserve the\n * stored record as-is.\n */\nconst matchRecordInfo = <TSchema extends RecordSchema>(\n schema: TSchema,\n info: GenericRecord | null | undefined,\n): RecordInfo<InferInput<TSchema>> | null =>\n info && schema.$matches(info.record, { strict: false })\n ? { ...info, record: info.record }\n : null\n\n/**\n * Store a generic record in the map matching its collection. Records failing\n * Lexicon validation are stored as null.\n */\nconst setSiteStandardRecord = (\n out: SiteStandardRecords,\n uri: string,\n key: string,\n info: GenericRecord | null | undefined,\n) => {\n switch (siteStandardKind(uri)) {\n case 'documents':\n out.documents.set(key, matchRecordInfo(site.standard.document.main, info))\n break\n case 'publications':\n out.publications.set(\n key,\n matchRecordInfo(site.standard.publication.main, info),\n )\n break\n }\n}\n\n/**\n * Read-path resolution: caller pinned a set of `(uri, cid)` strongRefs in\n * the post at write time, and we honor those exact versions. Any pair\n * that doesn't structurally agree is rejected, so downstream callers can\n * trust the returned shape.\n *\n * Same observable contract as\n * `getSiteStandardRecordsFromHydrationMapsByDocumentUri` (the compose-path\n * sister) — both functions guarantee that a returned `(doc, pub)` pair\n * has matching site/uri, and reject orphan docs that claim a\n * non-hydrated publication. They differ only in how upstream availability\n * is asserted: this one trusts caller-supplied refs; the sister derives\n * everything from the dataplane response.\n *\n * Pairing rules:\n * - Both slots referenced: `doc.site` must equal `publication.ref.uri`,\n * else both come back `undefined`.\n * - Doc with at-uri `site` referenced but no matching publication ref:\n * reject the whole pairing (doc claims a publication that should have\n * been pinned, but wasn't).\n * - Loose doc (web-URL `site`) referenced: publication stays `undefined`.\n * - Only a publication referenced: document stays `undefined`.\n *\n * Each returned slot carries the matching `ref` so callers can recover\n * the owner DID for blob-cdn URL building, etc.\n */\nexport const getSiteStandardRecordsFromHydrationMapsByRefs = (\n associatedRefs: readonly { uri: AtUriString; cid: string }[] | undefined,\n documents: SiteStandardDocuments | undefined,\n publications: SiteStandardPublications | undefined,\n): {\n document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n publication: AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n} => {\n if (!associatedRefs?.length) {\n return { document: undefined, publication: undefined }\n }\n\n // Resolve each ref against the hydration maps, taking the first hit on\n // each side.\n let document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n let publication:\n AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n for (const ref of associatedRefs) {\n const key = genericRecordKey(ref.uri, ref.cid)\n if (!document) {\n const hit = documents?.get(key)\n if (hit) document = { ref, info: hit }\n }\n if (!publication) {\n const hit = publications?.get(key)\n if (hit) publication = { ref, info: hit }\n }\n if (document && publication) break\n }\n\n // Both refs resolved: enforce that the doc's `site` actually points at\n // the supplied publication. Mismatch means the post was misconstructed\n // (or tampered with), so reject the whole pairing.\n if (document && publication) {\n if (document.info.record.site !== publication.ref.uri) {\n hydrationLogger.warn(\n {\n documentUri: document.ref.uri,\n documentSite: document.info.record.site,\n publicationUri: publication.ref.uri,\n },\n 'site.standard byRefs lookup failed: doc.site does not match hydrated publication.uri',\n )\n return { document: undefined, publication: undefined }\n }\n }\n\n // Doc with at-uri `site` but no publication: the post should have\n // pinned the publication too. Treat as misconstructed — same contract\n // as the compose-path lookup.\n if (document && !publication) {\n const site = document.info.record.site\n if (site && site.startsWith('at://')) {\n hydrationLogger.warn(\n { documentUri: document.ref.uri, documentSite: site },\n 'site.standard byRefs lookup failed: document.site is AT URI but no matching publication was hydrated',\n )\n return { document: undefined, publication: undefined }\n }\n }\n\n return { document, publication }\n}\n\n/**\n * Compose-path resolution: no caller-supplied refs — the dataplane\n * returned the latest version of each record (including any\n * publications it auto-resolved from a document's `site` field). Take\n * the first hydrated document and pair it with the publication its\n * `site` field points at.\n *\n * Same observable contract as\n * `getSiteStandardRecordsFromHydrationMapsByRefs` (the read-path\n * sister) — both functions guarantee that a returned `(doc, pub)` pair\n * has matching site/uri, and reject orphan docs that claim a\n * non-hydrated publication. They differ only in how upstream\n * availability is asserted: this one walks whatever was returned by the\n * dataplane; the sister checks against caller-supplied refs.\n *\n * Pairing rules:\n * - Doc with at-uri `site`: must find a hydrated publication at that\n * URI. If none was hydrated, the doc/publication chain is incomplete\n * and the function returns `undefined` for both slots; the doc alone\n * isn't useful without its source (can't verify the pub)\n * - Doc with web-URL `site` (loose): no publication.\n * - No doc hydrated: fall through to the first hydrated publication for\n * the publication-only resolution flow.\n */\nexport const getSiteStandardRecordsFromHydrationMapsByDocumentUri = (\n documents: SiteStandardDocuments | undefined,\n publications: SiteStandardPublications | undefined,\n): {\n document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n publication: AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n} => {\n // First hydrated doc.\n let document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n for (const [key, info] of documents ?? []) {\n if (!info) continue\n document = { ref: parseGenericRecordKey(key), info }\n break\n }\n\n let publication:\n AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n if (document) {\n const site = document.info.record.site\n if (site && site.startsWith('at://')) {\n // Doc declared an at-uri publication; we need it.\n for (const [key, info] of publications ?? []) {\n if (!info) continue\n const ref = parseGenericRecordKey(key)\n if (ref.uri === site) {\n publication = { ref, info }\n break\n }\n }\n if (!publication) {\n hydrationLogger.warn(\n { documentUri: document.ref.uri, documentSite: site },\n 'site.standard byDocumentUri lookup failed: document.site is AT URI but no matching publication was hydrated',\n )\n return { document: undefined, publication: undefined }\n }\n }\n // else: loose doc (web-URL site), no publication needed.\n } else {\n // Publication-only flow: no doc, take the first hydrated publication.\n for (const [key, info] of publications ?? []) {\n if (!info) continue\n publication = { ref: parseGenericRecordKey(key), info }\n break\n }\n }\n\n return { document, publication }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"external.js","sourceRoot":"","sources":["../../src/hydration/external.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AtUriString,\n type DidString,\n type InferInput,\n type NsidString,\n type RecordSchema,\n type TypedLexMap,\n isTypedLexMap,\n lexParseJsonBytes,\n} from '@atproto/lex'\nimport { parseAtUriString } from '@atproto/syntax'\nimport type { DataPlaneClient } from '../data-plane/client/index.js'\nimport { site } from '../lexicons/index.js'\nimport { hydrationLogger } from '../logger.js'\nimport {\n type RecordLookupResult,\n RecordLookupStatus,\n} from '../proto/bsky_pb.js'\nimport {\n type ExternalHydrationOutcome,\n type ExternalHydrationRoot,\n type ExternalHydrationWork,\n events,\n} from '../telemetry/events.js'\nimport { uriToDid } from '../util/uris.js'\nimport type {\n SiteStandardDocumentRecord,\n SiteStandardPublicationRecord,\n} from '../views/types.js'\nimport type { Actors } from './actor.js'\nimport type { Labels } from './label.js'\nimport {\n HydrationMap,\n type ItemRef,\n type RecordInfo,\n parseDate,\n safeTakedownRef,\n} from './util.js'\n\n/** Generic record bodies are decoded, but not validated against a Lexicon. */\nexport type ExternalRecord = RecordInfo<TypedLexMap>\nexport type ExternalRecords = HydrationMap<AtUriString, ExternalRecord>\n/** Keyed by `genericRecordKey({ uri, cid })` to retain versions of a URI. */\nexport type ExternalRecordsByRef = HydrationMap<ExactRecordKey, ExternalRecord>\nexport type ExternalRecordBacklinks = HydrationMap<AtUriString, AtUriString[]>\n\nexport type AtmosphereActivityItem = {\n uri: AtUriString\n sortedAt: Date\n}\n\nexport type AtmosphereTimeline = {\n items: AtmosphereActivityItem[]\n cursor?: string\n}\n\nexport type AtmosphereBacklinks = {\n backlinks: AtmosphereActivityItem[]\n cursor?: string\n}\n\nexport type ExternalRecordBacklinkCounts = HydrationMap<\n AtUriString,\n Partial<Record<NsidString, number>>\n>\n\nexport type AtmosphereBacklinksByActor = {\n backlinks: HydrationMap<AtUriString, AtUriString[]>\n truncated: boolean\n}\n\ndeclare const exactRecordKeySymbol: unique symbol\n\n/**\n * A version-exact `${uri}@${cid}` key, only produced by `genericRecordKey` for\n * a ref with a CID, so it can be parsed back by `parseGenericRecordKey`.\n */\nexport type ExactRecordKey = string & { [exactRecordKeySymbol]: true }\n\nexport type SiteStandardDocument = RecordInfo<SiteStandardDocumentRecord>\nexport type SiteStandardPublication = RecordInfo<SiteStandardPublicationRecord>\n\n/**\n * Keyed by `${uri}@${cid}` — see `genericRecordKey`. A single hydration\n * batch can pull more than one version of the same URI (different posts\n * pinning different cids), so the composite key is needed for O(1)\n * version-exact lookups.\n */\nexport type SiteStandardDocuments = HydrationMap<\n ExactRecordKey,\n SiteStandardDocument\n>\n/**\n * Keyed by `${uri}@${cid}`. See `SiteStandardDocuments` for the rationale.\n */\nexport type SiteStandardPublications = HydrationMap<\n ExactRecordKey,\n SiteStandardPublication\n>\nexport type SiteStandardRecords = {\n documents: SiteStandardDocuments\n publications: SiteStandardPublications\n}\n\nexport class ExternalHydrator {\n static readonly MAX_BACKLINK_PREVIEWS = 3\n static readonly MAX_BACKLINK_GALLERY_ITEMS = 10\n static readonly MAX_BACKLINK_FANOUT = 8\n /** Hard cap on generic batches per traversal, counting the root as pass 1. */\n static readonly MAX_EXTERNAL_HYDRATION_PASSES = 8\n\n constructor(public dataplane: DataPlaneClient) {}\n\n /** Fetch exact record versions; unavailable records are represented by null. */\n async getRecordsByRef(\n refs: Required<ItemRef>[],\n includeTakedowns = false,\n ): Promise<ExternalRecordsByRef> {\n const map: ExternalRecordsByRef = new HydrationMap()\n if (!refs.length) return map\n\n const res = await this.dataplane.getRecordsByRef({ refs })\n for (let i = 0; i < refs.length; i++) {\n map.set(\n genericRecordKey(refs[i]),\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\n }\n return map\n }\n\n /** Fetch the latest indexed versions without collection-specific validation. */\n async getRecordsByURI(\n uris: AtUriString[],\n includeTakedowns = false,\n ): Promise<ExternalRecords> {\n const map: ExternalRecords = new HydrationMap()\n if (!uris.length) return map\n\n const res = await this.dataplane.getRecordsByURI({ uris })\n for (let i = 0; i < uris.length; i++) {\n map.set(\n uris[i],\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\n }\n return map\n }\n\n /** Fetch a page of activity refs for subsequent generic record hydration. */\n async getAtmosphereTimeline(\n viewerDid: DidString,\n opts: { limit?: number; cursor?: string } = {},\n ): Promise<AtmosphereTimeline> {\n const res = await this.dataplane.getAtmosphereTimeline({\n viewerDid,\n ...opts,\n })\n return {\n items: res.items.map((item) => ({\n uri: item.uri as AtUriString,\n sortedAt: parseDate(item.sortedAt) ?? new Date(0),\n })),\n cursor: res.cursor || undefined,\n }\n }\n\n /** Fetch source-record counts, optionally restricted to one collection. */\n async getAtmosphereBacklinkCounts(\n targetUris: AtUriString[],\n collection?: NsidString,\n ): Promise<ExternalRecordBacklinkCounts> {\n const map: ExternalRecordBacklinkCounts = new HydrationMap()\n if (!targetUris.length) return map\n\n const res = await this.dataplane.getAtmosphereBacklinkCounts({\n targetUris,\n collection,\n })\n for (const result of res.results) {\n map.set(\n result.targetUri as AtUriString,\n Object.fromEntries(\n Object.entries(result.counts).map(([nsid, count]) => [\n nsid,\n Number(count),\n ]),\n ),\n )\n }\n return map\n }\n\n /** Fetch a page of source records linking to a target. */\n async getAtmosphereBacklinks(\n targetUri: AtUriString,\n collection: NsidString,\n opts: { limit?: number; cursor?: string } = {},\n ): Promise<AtmosphereBacklinks> {\n const res = await this.dataplane.getAtmosphereBacklinks({\n targetUri,\n collection,\n ...opts,\n })\n return {\n backlinks: res.backlinks.map((backlink) => ({\n uri: backlink.uri as AtUriString,\n sortedAt: parseDate(backlink.sortedAt) ?? new Date(0),\n })),\n cursor: res.cursor || undefined,\n }\n }\n\n /** Fetch an actor's links per target, retaining the batch truncation flag. */\n async getAtmosphereBacklinksByActor(\n targetUris: AtUriString[],\n actorDid: DidString,\n collection: NsidString,\n ): Promise<AtmosphereBacklinksByActor> {\n const backlinks: AtmosphereBacklinksByActor['backlinks'] =\n new HydrationMap()\n if (!targetUris.length) return { backlinks, truncated: false }\n\n const res = await this.dataplane.getAtmosphereBacklinksByActor({\n targetUris,\n actorDid,\n collection,\n })\n for (const result of res.results) {\n backlinks.set(\n result.targetUri as AtUriString,\n result.uris as AtUriString[],\n )\n }\n return { backlinks, truncated: res.truncated }\n }\n\n /**\n * Fetch exact `site.standard.{document,publication}` versions. Does NOT\n * resolve a document's publication; callers must pin it explicitly.\n */\n async getSiteStandardRecordsByRef(\n refs: ItemRef[],\n includeTakedowns = false,\n ): Promise<SiteStandardRecords> {\n const ssRefs = refs.filter(\n (ref): ref is Required<ItemRef> =>\n !!ref.cid && siteStandardKind(ref.uri) !== undefined,\n )\n const out = emptySiteStandardRecords()\n if (!ssRefs.length) return out\n\n const records = await this.getRecordsByRef(ssRefs, includeTakedowns)\n for (const [key, info] of records) {\n setSiteStandardRecord(out, parseGenericRecordKey(key).uri, key, info)\n }\n return out\n }\n}\n\n/**\n * Composes the lookup key for a ref: the bare URI for a latest-version lookup,\n * or `${uri}@${cid}` for an exact version. A single hydration batch can pull\n * several versions of one URI (different posts pinning different cids), so\n * exact maps need the composite for O(1) version-exact lookups. The two forms\n * never collide, so latest and exact lookups can share one traversal set.\n *\n * Throws on an empty CID rather than treating it as a latest lookup.\n */\nexport function genericRecordKey(ref: Required<ItemRef>): ExactRecordKey\nexport function genericRecordKey(ref: ItemRef): string\nexport function genericRecordKey({ uri, cid }: ItemRef): string {\n if (cid === undefined) return uri\n if (!cid) throw new Error(`Empty CID in record key for ${uri}`)\n return `${uri}@${cid}`\n}\n\n/**\n * Recover the URI and CID from an exact record key, splitting at the last `@`.\n * Throws if either part is missing. Components are trusted, not revalidated.\n */\nexport function parseGenericRecordKey(key: ExactRecordKey): Required<ItemRef> {\n const at = key.lastIndexOf('@')\n if (at <= 0 || at === key.length - 1) {\n throw new Error(`Malformed exact record key: ${key}`)\n }\n return {\n uri: key.slice(0, at) as AtUriString,\n cid: key.slice(at + 1),\n }\n}\n\n/**\n * Null generic external records (in both the URI-keyed and exact-ref maps,\n * keeping their keys) that are taken down by an actionable label, unless\n * takedowns are included, or whose owner is explicitly unavailable. Applies to\n * each record independently; counts and other records are unaffected.\n */\nexport function actionExternalRecordTakedowns(\n {\n externalRecords,\n externalRecordsByRef,\n actors,\n labels,\n }: {\n externalRecords?: ExternalRecords\n externalRecordsByRef?: ExternalRecordsByRef\n actors?: Actors\n labels?: Labels\n },\n includeTakedowns?: boolean,\n): void {\n // An absent actor entry was not hydrated; only `null` means unavailable.\n const isHidden = (uri: AtUriString) =>\n actors?.get(uriToDid(uri)) === null ||\n (!includeTakedowns && labels?.get(uri)?.isTakendown)\n for (const [uri, info] of externalRecords ?? []) {\n if (!info || !isHidden(uri)) continue\n externalRecords?.set(uri, null)\n externalRecordsByRef?.set(genericRecordKey({ uri, cid: info.cid }), null)\n }\n // Every exact version is checked on its own; versions are never collapsed.\n for (const [key, info] of externalRecordsByRef ?? []) {\n if (info && isHidden(parseGenericRecordKey(key).uri)) {\n externalRecordsByRef?.set(key, null)\n }\n }\n}\n\n/**\n * Generic lookup work of one external hydration traversal, shared by reference\n * through its nested passes. `capped` records hitting the pass limit.\n */\nexport type ExternalHydrationTracker = ExternalHydrationWork & {\n capped: boolean\n}\n\n/**\n * Run `fn` with the caller's tracker, or as the owner of a new traversal when\n * there is none. Only the owner reports, once, including on failure. Owners\n * that completed without scheduling a batch did no work and are not reported;\n * caps and failures always are.\n */\nexport async function trackExternalHydration<T>(\n root: ExternalHydrationRoot,\n hydrationMetrics: ExternalHydrationTracker | undefined,\n fn: (hydrationMetrics: ExternalHydrationTracker) => Promise<T>,\n): Promise<T> {\n if (hydrationMetrics) return fn(hydrationMetrics)\n const owned = { recordLookups: 0, batches: 0, maxPass: 0, capped: false }\n let outcome: ExternalHydrationOutcome = 'failed'\n try {\n const state = await fn(owned)\n outcome = owned.capped ? 'capped' : 'completed'\n return state\n } finally {\n if (owned.batches || outcome !== 'completed') {\n const { recordLookups, batches, maxPass } = owned\n events.externalHydrationTraversal({\n root,\n outcome,\n recordLookups,\n batches,\n maxPass,\n })\n }\n }\n}\n\nfunction parseGenericRecord(\n result: RecordLookupResult | undefined,\n includeTakedowns: boolean,\n): ExternalRecord | undefined {\n if (\n result?.status !== RecordLookupStatus.FOUND &&\n !(includeTakedowns && result?.status === RecordLookupStatus.TAKEN_DOWN)\n ) {\n return undefined\n }\n const entry = result.record\n if (!entry?.cid || !entry.record.byteLength) return undefined\n if (!includeTakedowns && entry.takenDown) return undefined\n\n let record: ReturnType<typeof lexParseJsonBytes>\n try {\n record = lexParseJsonBytes(entry.record, { strict: false })\n } catch {\n return undefined\n }\n if (!isTypedLexMap(record)) return undefined\n\n return {\n record,\n cid: entry.cid,\n sortedAt: parseDate(entry.sortedAt) ?? new Date(0),\n indexedAt: parseDate(entry.indexedAt) ?? new Date(0),\n takedownRef: safeTakedownRef(entry),\n }\n}\n\nconst emptySiteStandardRecords = (): SiteStandardRecords => ({\n documents: new HydrationMap(),\n publications: new HydrationMap(),\n})\n\nconst siteStandardKind = (\n uri: string,\n): keyof SiteStandardRecords | undefined => {\n const parsed = parseAtUriString(uri)\n if (!parsed.success) return undefined\n switch (parsed.value.collection) {\n case site.standard.document.$type:\n return 'documents'\n case site.standard.publication.$type:\n return 'publications'\n default:\n return undefined\n }\n}\n\n/**\n * Generic record bodies are unvalidated, so check them against the Lexicon\n * before exposing typed fields. Parse mode is not used, to preserve the\n * stored record as-is.\n */\nconst matchRecordInfo = <TSchema extends RecordSchema>(\n schema: TSchema,\n info: ExternalRecord | null | undefined,\n): RecordInfo<InferInput<TSchema>> | null =>\n info && schema.$matches(info.record, { strict: false })\n ? { ...info, record: info.record }\n : null\n\n/**\n * Store a generic record in the map matching its collection. Records failing\n * Lexicon validation are stored as null.\n */\nconst setSiteStandardRecord = (\n out: SiteStandardRecords,\n uri: string,\n key: ExactRecordKey,\n info: ExternalRecord | null | undefined,\n) => {\n switch (siteStandardKind(uri)) {\n case 'documents':\n out.documents.set(key, matchRecordInfo(site.standard.document.main, info))\n break\n case 'publications':\n out.publications.set(\n key,\n matchRecordInfo(site.standard.publication.main, info),\n )\n break\n }\n}\n\nexport type AssociatedSiteStandardRecord<T> = {\n ref: { uri: AtUriString; cid: string }\n info: T\n}\n\n/**\n * Read-path resolution: caller pinned a set of `(uri, cid)` strongRefs in\n * the post at write time, and we honor those exact versions. Any pair\n * that doesn't structurally agree is rejected, so downstream callers can\n * trust the returned shape.\n *\n * Pairing rules:\n * - Both slots referenced: `doc.site` must equal `publication.ref.uri`,\n * else both come back `undefined`.\n * - Doc with at-uri `site` referenced but no matching publication ref:\n * reject the whole pairing (doc claims a publication that should have\n * been pinned, but wasn't).\n * - Loose doc (web-URL `site`) referenced: publication stays `undefined`.\n * - Only a publication referenced: document stays `undefined`.\n *\n * Each returned slot carries the matching `ref` so callers can recover\n * the owner DID for blob-cdn URL building, etc.\n */\nexport const getSiteStandardRecordsFromHydrationMapsByRefs = (\n associatedRefs: readonly { uri: AtUriString; cid: string }[] | undefined,\n documents: SiteStandardDocuments | undefined,\n publications: SiteStandardPublications | undefined,\n): {\n document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n publication: AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n} => {\n if (!associatedRefs?.length) {\n return { document: undefined, publication: undefined }\n }\n\n // Resolve each ref against the hydration maps, taking the first hit on\n // each side.\n let document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n let publication:\n AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n for (const ref of associatedRefs) {\n const key = genericRecordKey(ref)\n if (!document) {\n const hit = documents?.get(key)\n if (hit) document = { ref, info: hit }\n }\n if (!publication) {\n const hit = publications?.get(key)\n if (hit) publication = { ref, info: hit }\n }\n if (document && publication) break\n }\n\n // Both refs resolved: enforce that the doc's `site` actually points at\n // the supplied publication. Mismatch means the post was misconstructed\n // (or tampered with), so reject the whole pairing.\n if (document && publication) {\n if (document.info.record.site !== publication.ref.uri) {\n hydrationLogger.warn(\n {\n documentUri: document.ref.uri,\n documentSite: document.info.record.site,\n publicationUri: publication.ref.uri,\n },\n 'site.standard byRefs lookup failed: doc.site does not match hydrated publication.uri',\n )\n return { document: undefined, publication: undefined }\n }\n }\n\n // Doc with at-uri `site` but no publication: the post should have\n // pinned the publication too. Treat as misconstructed.\n if (document && !publication) {\n const site = document.info.record.site\n if (site && site.startsWith('at://')) {\n hydrationLogger.warn(\n { documentUri: document.ref.uri, documentSite: site },\n 'site.standard byRefs lookup failed: document.site is AT URI but no matching publication was hydrated',\n )\n return { document: undefined, publication: undefined }\n }\n }\n\n return { document, publication }\n}\n"]}
|
|
@@ -5,8 +5,8 @@ import type { FeatureGatesClient, ScopedFeatureGatesClient } from '../feature-ga
|
|
|
5
5
|
import { app } from '../lexicons/index.js';
|
|
6
6
|
import type { BookmarkInfo, Notification } from '../proto/bsky_pb.js';
|
|
7
7
|
import type { ParsedLabelers } from '../util.js';
|
|
8
|
-
import { type ActivitySubscriptionStates, ActorHydrator, type Actors, type KnownFollowersStates, type KnownLikersStates, type ProfileAggs, type ProfileViewerStates } from './actor.js';
|
|
9
|
-
import { ExternalHydrator, type SiteStandardDocuments, type SiteStandardPublications } from './external.js';
|
|
8
|
+
import { type ActivitySubscriptionStates, ActorHydrator, type Actors, type KnownFollowersStates, type KnownLikersStates, type ProfileAggs, type ProfileLinks, type ProfileViewerStates } from './actor.js';
|
|
9
|
+
import { type ExternalHydrationTracker, ExternalHydrator, type ExternalRecordBacklinkCounts, type ExternalRecordBacklinks, type ExternalRecords, type ExternalRecordsByRef, type SiteStandardDocuments, type SiteStandardPublications } from './external.js';
|
|
10
10
|
import { type FeedGenAggs, type FeedGenViewerStates, type FeedGens, FeedHydrator, type FeedItem, type GetPostsHydrationOptions, type Likes, type Post, type PostAggs, type PostViewerStates, type Postgates, type Posts, type Reposts, type ThreadContexts, type Threadgates } from './feed.js';
|
|
11
11
|
import { type Follows, GraphHydrator, type ListAggs, type ListItems, type ListMembershipStates, type ListViewerStates, type Lists, type StarterPackAggs, type StarterPacks, type Verifications } from './graph.js';
|
|
12
12
|
import { LabelHydrator, type LabelerAggs, type LabelerViewerStates, type Labelers, Labels } from './label.js';
|
|
@@ -68,6 +68,7 @@ export type HydrationState = {
|
|
|
68
68
|
feedgenAggs?: FeedGenAggs;
|
|
69
69
|
starterPacks?: StarterPacks;
|
|
70
70
|
starterPackAggs?: StarterPackAggs;
|
|
71
|
+
profileLinks?: ProfileLinks;
|
|
71
72
|
labelers?: Labelers;
|
|
72
73
|
labelerViewers?: LabelerViewerStates;
|
|
73
74
|
labelerAggs?: LabelerAggs;
|
|
@@ -77,6 +78,11 @@ export type HydrationState = {
|
|
|
77
78
|
bidirectionalBlocks?: BidirectionalBlocks;
|
|
78
79
|
verifications?: Verifications;
|
|
79
80
|
bookmarks?: Bookmarks;
|
|
81
|
+
externalRecords?: ExternalRecords;
|
|
82
|
+
externalRecordsByRef?: ExternalRecordsByRef;
|
|
83
|
+
/** Available backlink source URIs per target, potentially from a partial page. */
|
|
84
|
+
externalRecordBacklinks?: ExternalRecordBacklinks;
|
|
85
|
+
externalRecordBacklinkCounts?: ExternalRecordBacklinkCounts;
|
|
80
86
|
siteStandardDocuments?: SiteStandardDocuments;
|
|
81
87
|
siteStandardPublications?: SiteStandardPublications;
|
|
82
88
|
};
|
|
@@ -95,6 +101,10 @@ type HydrateFeedItemsOptions = {
|
|
|
95
101
|
*/
|
|
96
102
|
knownLikers?: boolean;
|
|
97
103
|
};
|
|
104
|
+
export type HydrateProfilesOptions = {
|
|
105
|
+
knownFollowersDids?: DidString[];
|
|
106
|
+
activitySubscriptions?: boolean;
|
|
107
|
+
};
|
|
98
108
|
export type PostBlock = {
|
|
99
109
|
embed: boolean;
|
|
100
110
|
parent: boolean;
|
|
@@ -134,11 +144,11 @@ export declare class Hydrator {
|
|
|
134
144
|
config: HydratorConfig;
|
|
135
145
|
constructor(dataplane: DataPlaneClient, serviceLabelers: readonly DidString[] | undefined, config: HydratorConfig);
|
|
136
146
|
hydrateProfileViewers(dids: DidString[], ctx: HydrateCtx): Promise<HydrationState>;
|
|
137
|
-
hydrateProfiles(dids: DidString[], ctx: HydrateCtx): Promise<HydrationState>;
|
|
138
|
-
hydrateProfilesBasic(dids: DidString[], ctx: HydrateCtx): Promise<HydrationState>;
|
|
139
|
-
hydrateProfilesDetailed(dids: DidString[], ctx: HydrateCtx, opts?:
|
|
140
|
-
|
|
141
|
-
|
|
147
|
+
hydrateProfiles(dids: DidString[], ctx: HydrateCtx, opts?: HydrateProfilesOptions): Promise<HydrationState>;
|
|
148
|
+
hydrateProfilesBasic(dids: DidString[], ctx: HydrateCtx, opts?: HydrateProfilesOptions): Promise<HydrationState>;
|
|
149
|
+
hydrateProfilesDetailed(dids: DidString[], ctx: HydrateCtx, opts?: HydrateProfilesOptions): Promise<HydrationState>;
|
|
150
|
+
private hydrateProfilesWorker;
|
|
151
|
+
private hydrateProfileState;
|
|
142
152
|
hydrateLists(uris: AtUriString[], ctx: HydrateCtx): Promise<HydrationState>;
|
|
143
153
|
hydrateListsBasic(uris: AtUriString[], ctx: HydrateCtx, opts?: {
|
|
144
154
|
skipAuthors: boolean;
|
|
@@ -151,12 +161,38 @@ export declare class Hydrator {
|
|
|
151
161
|
private hydratePostBlocks;
|
|
152
162
|
hydrateFeedItems(items: FeedItem[], ctx: HydrateCtx, options?: HydrateFeedItemsOptions): Promise<HydrationState>;
|
|
153
163
|
/**
|
|
154
|
-
* Hydrate the
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
164
|
+
* Hydrate the latest versions of external records, plus labels, profiles, and
|
|
165
|
+
* their view dependencies. `hydrationPass` is the 1-based number of this
|
|
166
|
+
* generic batch within the traversal (the root batch is pass 1); nested
|
|
167
|
+
* batches continue the count. Nested passes share the caller's
|
|
168
|
+
* `hydrationMetrics` tracker; without one, this call owns the traversal and
|
|
169
|
+
* reports its totals.
|
|
158
170
|
*/
|
|
159
|
-
hydrateEmbedExternalViewFromUris(uris: AtUriString[], ctx: HydrateCtx): Promise<HydrationState>;
|
|
171
|
+
hydrateEmbedExternalViewFromUris(uris: AtUriString[], ctx: HydrateCtx, seenRecordKeys?: Set<string>, hydrationPass?: number, hydrationMetrics?: ExternalHydrationTracker): Promise<HydrationState>;
|
|
172
|
+
/**
|
|
173
|
+
* Like `hydrateEmbedExternalViewFromUris`, but for exact record versions
|
|
174
|
+
* pinned by strong refs. Roots land only in `externalRecordsByRef`; their
|
|
175
|
+
* URI dependencies are hydrated as latest versions by the URI path.
|
|
176
|
+
*/
|
|
177
|
+
hydrateEmbedExternalViewFromRefs(refs: Required<ItemRef>[], ctx: HydrateCtx, seenRecordKeys?: Set<string>, hydrationPass?: number, hydrationMetrics?: ExternalHydrationTracker): Promise<HydrationState>;
|
|
178
|
+
private hydrateEmbedExternalView;
|
|
179
|
+
/**
|
|
180
|
+
* Discover view dependencies by URI collection and hydrate new URIs in a batch.
|
|
181
|
+
* Returns additional state. Each input is inspected in the map matching its
|
|
182
|
+
* identity: `(uri, cid)` refs in `externalRecordsByRef`, bare URIs in
|
|
183
|
+
* `externalRecords`. Every pinned version is inspected, since versions of
|
|
184
|
+
* one URI can reference different dependencies.
|
|
185
|
+
*
|
|
186
|
+
* `seenRecordKeys` prevents repeated lookups and cycles across nested passes,
|
|
187
|
+
* but not a chain of distinct URIs; `MAX_EXTERNAL_HYDRATION_PASSES` bounds
|
|
188
|
+
* that, as a guard against future association rules or unexpected expansion.
|
|
189
|
+
* `hydrationPass` is the number of the generic batch that produced `state`
|
|
190
|
+
* (1-based, default 1 for prehydrated state, which is treated as the root
|
|
191
|
+
* batch); the next nested batch is `hydrationPass + 1`. `hydrationMetrics`
|
|
192
|
+
* is shared as in `hydrateEmbedExternalViewFromUris`.
|
|
193
|
+
*/
|
|
194
|
+
hydrateExternalViewDependencies(state: HydrationState, refs: ItemRef[], ctx: HydrateCtx, seenRecordKeys?: Set<string>, hydrationPass?: number, hydrationMetrics?: ExternalHydrationTracker): Promise<HydrationState>;
|
|
195
|
+
private discoverExternalViewDependencies;
|
|
160
196
|
hydrateThreadPosts(refs: ItemRef[], ctx: HydrateCtx, options?: Pick<HydratePostsOptions, 'knownLikers'>): Promise<HydrationState>;
|
|
161
197
|
private hydrateKnownLikers;
|
|
162
198
|
hydrateFeedGens(uris: AtUriString[], // @TODO any way to get refs here?
|
|
@@ -166,13 +202,15 @@ export declare class Hydrator {
|
|
|
166
202
|
hydrateLikes(authorDid: DidString, uris: AtUriString[], ctx: HydrateCtx): Promise<HydrationState>;
|
|
167
203
|
hydrateReposts(uris: AtUriString[], ctx: HydrateCtx): Promise<HydrationState>;
|
|
168
204
|
hydrateNotifications(notifs: Notification[], ctx: HydrateCtx): Promise<HydrationState>;
|
|
169
|
-
hydrateGroupedNotifications(notifs: RawNotification[], ctx: HydrateCtx
|
|
205
|
+
hydrateGroupedNotifications(notifs: RawNotification[], ctx: HydrateCtx, opts?: {
|
|
206
|
+
knownFollowersDids?: DidString[];
|
|
207
|
+
}): Promise<HydrationState>;
|
|
170
208
|
hydrateBookmarks(bookmarkInfos: BookmarkInfo[], ctx: HydrateCtx): Promise<HydrationState>;
|
|
171
209
|
hydrateFollows(uris: AtUriString[], ctx: HydrateCtx): Promise<HydrationState>;
|
|
172
210
|
hydrateBidirectionalBlocks(didMap: Map<DidString, DidString[]>, // DID -> DID[]
|
|
173
211
|
ctx: HydrateCtx): Promise<BidirectionalBlocks>;
|
|
174
212
|
hydrateLabelers(dids: DidString[], ctx: HydrateCtx): Promise<HydrationState>;
|
|
175
|
-
getRecord(uri: AtUriString, includeTakedowns?: boolean): Promise<import("./graph.js").Block | import("./actor.js").ChatDeclaration | import("./feed.js").FeedGen | import("./graph.js").Follow | import("./actor.js").GermDeclaration | import("./label.js").Labeler | import("./feed.js").Like | import("./graph.js").List | import("./graph.js").ListItem | import("./actor.js").NotificationDeclaration | import("./feed.js").Postgate | RecordInfo<app.bsky.actor.profile.Main> | import("./feed.js").Repost | import("./graph.js").StarterPack | import("./actor.js").Status | import("./feed.js").Threadgate | Post | undefined>;
|
|
213
|
+
getRecord(uri: AtUriString, includeTakedowns?: boolean): Promise<import("./graph.js").Block | import("./actor.js").ChatDeclaration | import("./feed.js").FeedGen | import("./graph.js").Follow | import("./actor.js").GermDeclaration | import("./label.js").Labeler | import("./feed.js").Like | import("./graph.js").List | import("./graph.js").ListItem | import("./actor.js").NotificationDeclaration | import("./feed.js").Postgate | import("./actor.js").ProfileLink | RecordInfo<app.bsky.actor.profile.Main> | import("./feed.js").Repost | import("./graph.js").StarterPack | import("./actor.js").Status | import("./feed.js").Threadgate | Post | undefined>;
|
|
176
214
|
createContext<V extends Omit<HydrateCtxVals, 'features'> & {
|
|
177
215
|
features?: ScopedFeatureGatesClient;
|
|
178
216
|
}>(vals: V): Promise<HydrateCtx & {
|
|
@@ -180,6 +218,11 @@ export declare class Hydrator {
|
|
|
180
218
|
}>;
|
|
181
219
|
resolveUri(uriStr: AtUriString): Promise<AtUriString>;
|
|
182
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* The link records a profile points to, in order. Only the first
|
|
223
|
+
* MAX_PROFILE_LINKS are shown, and only links in the profile's own repo count.
|
|
224
|
+
*/
|
|
225
|
+
export declare const profileLinkUris: (dids: DidString[], actors: Actors | undefined) => AtUriString[];
|
|
183
226
|
export declare const mergeStates: (stateA: HydrationState, stateB: HydrationState) => HydrationState;
|
|
184
227
|
export declare const mergeManyStates: (...states: HydrationState[]) => HydrationState;
|
|
185
228
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hydrator.d.ts","sourceRoot":"","sources":["../../src/hydration/hydrator.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"hydrator.d.ts","sourceRoot":"","sources":["../../src/hydration/hydrator.ts"],"names":[],"mappings":"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"}
|