@atproto/bsky 0.3.12 → 0.4.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/api/app/bsky/notification/getGroupedNotifications.d.ts.map +1 -1
  3. package/dist/api/app/bsky/notification/getGroupedNotifications.js +14 -3
  4. package/dist/api/app/bsky/notification/getGroupedNotifications.js.map +1 -1
  5. package/dist/api/blob-resolver.d.ts.map +1 -1
  6. package/dist/api/blob-resolver.js +9 -8
  7. package/dist/api/blob-resolver.js.map +1 -1
  8. package/dist/config.d.ts +2 -2
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js +7 -6
  11. package/dist/config.js.map +1 -1
  12. package/dist/hydration/external.d.ts +52 -45
  13. package/dist/hydration/external.d.ts.map +1 -1
  14. package/dist/hydration/external.js +132 -114
  15. package/dist/hydration/external.js.map +1 -1
  16. package/dist/hydration/hydrator.d.ts +10 -8
  17. package/dist/hydration/hydrator.d.ts.map +1 -1
  18. package/dist/hydration/hydrator.js +82 -189
  19. package/dist/hydration/hydrator.js.map +1 -1
  20. package/dist/image/server.d.ts.map +1 -1
  21. package/dist/image/server.js +12 -1
  22. package/dist/image/server.js.map +1 -1
  23. package/dist/lexicons/tools/ozone/moderation/emitEvent.defs.d.ts +2 -2
  24. package/dist/lexicons/tools/ozone/moderation/emitEvent.defs.js.map +1 -1
  25. package/dist/lexicons/tools/ozone/report/closeReports.defs.d.ts +1 -1
  26. package/dist/lexicons/tools/ozone/report/closeReports.defs.d.ts.map +1 -1
  27. package/dist/lexicons/tools/ozone/report/closeReports.defs.js +1 -1
  28. package/dist/lexicons/tools/ozone/report/closeReports.defs.js.map +1 -1
  29. package/dist/telemetry/events.d.ts +11 -4
  30. package/dist/telemetry/events.d.ts.map +1 -1
  31. package/dist/telemetry/events.js +29 -5
  32. package/dist/telemetry/events.js.map +1 -1
  33. package/dist/util/external/standard-site.d.ts +2 -3
  34. package/dist/util/external/standard-site.d.ts.map +1 -1
  35. package/dist/util/external/standard-site.js +2 -3
  36. package/dist/util/external/standard-site.js.map +1 -1
  37. package/dist/util/uris.d.ts +5 -2
  38. package/dist/util/uris.d.ts.map +1 -1
  39. package/dist/util/uris.js +14 -1
  40. package/dist/util/uris.js.map +1 -1
  41. package/dist/views/index.d.ts +2 -2
  42. package/dist/views/index.d.ts.map +1 -1
  43. package/dist/views/index.js +17 -11
  44. package/dist/views/index.js.map +1 -1
  45. package/package.json +11 -12
@@ -1,24 +1,37 @@
1
1
  import { performance } from 'node:perf_hooks';
2
2
  import { chunkArray } from '@atproto/common';
3
- import { isTypedLexMap, lexParseJsonBytes, } from '@atproto/lex';
3
+ import { isDidString, isTypedLexMap, lexParseJsonBytes, } from '@atproto/lex';
4
4
  import { parseAtUriString } from '@atproto/syntax';
5
- import { site } from '../lexicons/index.js';
6
- import { hydrationLogger } from '../logger.js';
5
+ import { site, social } from '../lexicons/index.js';
7
6
  import { RecordLookupStatus, } from '../proto/bsky_pb.js';
8
7
  import { events, } from '../telemetry/events.js';
9
- import { uriToDid } from '../util/uris.js';
8
+ import { recordUriOf, uriToDid } from '../util/uris.js';
9
+ import { isExternalEmbedType, isRecordWithMediaType, } from '../views/types.js';
10
10
  import { HydrationMap, parseDate, safeTakedownRef, } from './util.js';
11
+ /**
12
+ * Per-collection sample limits. Basic hydration skips social previews,
13
+ * but keeps gallery items. Direct publication/photo references are singular.
14
+ */
15
+ export const EXTERNAL_HYDRATION_LIMITS = {
16
+ [site.standard.document.$type]: { recommendationPreviews: 3 },
17
+ [site.standard.publication.$type]: { subscriberPreviews: 3 },
18
+ [social.grain.gallery.$type]: { items: 10, favoritePreviews: 3 },
19
+ };
20
+ /** Maximum in-flight backlink sample RPCs, not a dependency-count limit. */
21
+ export const MAX_CONCURRENT_BACKLINK_REQUESTS = 8;
22
+ /** Maximum logical batches per traversal, counting the root as pass 1. */
23
+ export const MAX_EXTERNAL_HYDRATION_PASSES = 8;
11
24
  export class ExternalHydrator {
12
- static { this.MAX_BACKLINK_PREVIEWS = 3; }
13
- static { this.MAX_BACKLINK_GALLERY_ITEMS = 10; }
14
- static { this.MAX_BACKLINK_FANOUT = 8; }
15
- /** Hard cap on generic batches per traversal, counting the root as pass 1. */
16
- static { this.MAX_EXTERNAL_HYDRATION_PASSES = 8; }
17
25
  /**
18
26
  * Entries per generic record RPC. The dataplane rejects larger URI lookups;
19
27
  * exact-ref lookups use the same bound defensively.
20
28
  */
21
29
  static { this.MAX_RECORDS_PER_REQUEST = 100; }
30
+ /**
31
+ * Target URIs per backlink-count RPC. The dataplane requires between 1 and
32
+ * 100; this is a separate limit from `MAX_RECORDS_PER_REQUEST`.
33
+ */
34
+ static { this.MAX_BACKLINK_COUNT_TARGETS_PER_REQUEST = 100; }
22
35
  constructor(dataplane) {
23
36
  this.dataplane = dataplane;
24
37
  }
@@ -68,20 +81,24 @@ export class ExternalHydrator {
68
81
  cursor: res.cursor || undefined,
69
82
  };
70
83
  }
71
- /** Fetch source-record counts, optionally restricted to one collection. */
84
+ /**
85
+ * Fetch source-record counts, optionally restricted to one collection. Large
86
+ * inputs are fetched in sequential bounded requests; any failed request
87
+ * rejects the whole call.
88
+ */
72
89
  async getAtmosphereBacklinkCounts(targetUris, collection) {
73
90
  const map = new HydrationMap();
74
- if (!targetUris.length)
75
- return map;
76
- const res = await this.dataplane.getAtmosphereBacklinkCounts({
77
- targetUris,
78
- collection,
79
- });
80
- for (const result of res.results) {
81
- map.set(result.targetUri, Object.fromEntries(Object.entries(result.counts).map(([nsid, count]) => [
82
- nsid,
83
- Number(count),
84
- ])));
91
+ for (const chunk of chunkArray(targetUris, ExternalHydrator.MAX_BACKLINK_COUNT_TARGETS_PER_REQUEST)) {
92
+ const res = await this.dataplane.getAtmosphereBacklinkCounts({
93
+ targetUris: chunk,
94
+ collection,
95
+ });
96
+ for (const result of res.results) {
97
+ map.set(result.targetUri, Object.fromEntries(Object.entries(result.counts).map(([nsid, count]) => [
98
+ nsid,
99
+ Number(count),
100
+ ])));
101
+ }
85
102
  }
86
103
  return map;
87
104
  }
@@ -115,21 +132,6 @@ export class ExternalHydrator {
115
132
  }
116
133
  return { backlinks, truncated: res.truncated };
117
134
  }
118
- /**
119
- * Fetch exact `site.standard.{document,publication}` versions. Does NOT
120
- * resolve a document's publication; callers must pin it explicitly.
121
- */
122
- async getSiteStandardRecordsByRef(refs, includeTakedowns = false) {
123
- const ssRefs = refs.filter((ref) => !!ref.cid && siteStandardKind(ref.uri) !== undefined);
124
- const out = emptySiteStandardRecords();
125
- if (!ssRefs.length)
126
- return out;
127
- const records = await this.getRecordsByRef(ssRefs, includeTakedowns);
128
- for (const [key, info] of records) {
129
- setSiteStandardRecord(out, parseGenericRecordKey(key).uri, key, info);
130
- }
131
- return out;
132
- }
133
135
  }
134
136
  export function genericRecordKey({ uri, cid }) {
135
137
  if (cid === undefined)
@@ -180,9 +182,10 @@ export function actionExternalRecordTakedowns({ externalRecords, externalRecords
180
182
  * there is none. Only the owner reports, once, including on failure, with the
181
183
  * context's XRPC endpoint (`'unknown'` if unset) and the traversal's wall time. A
182
184
  * returned traversal is `capped` if it hit the pass limit, else `partial` if
183
- * it recovered from a dependency failure. Owners that completed without
184
- * scheduling a batch did no work and are not reported; other outcomes always
185
- * are.
185
+ * it recovered from a dependency failure. Owners that completed report when
186
+ * they scheduled a batch or inspected roots (even prehydrated or unavailable
187
+ * ones); only genuinely empty successful calls are not reported. Other
188
+ * outcomes always are.
186
189
  */
187
190
  export async function trackExternalHydration(root, xrpcEndpoint, hydrationMetrics, fn) {
188
191
  if (hydrationMetrics)
@@ -207,7 +210,7 @@ export async function trackExternalHydration(root, xrpcEndpoint, hydrationMetric
207
210
  return state;
208
211
  }
209
212
  finally {
210
- if (owned.batches || outcome !== 'completed') {
213
+ if (owned.batches > 0 || owned.roots > 0 || outcome !== 'completed') {
211
214
  events.externalHydrationTraversal({
212
215
  xrpcEndpoint: xrpcEndpoint ?? 'unknown',
213
216
  root,
@@ -251,10 +254,6 @@ function parseGenericRecord(result, includeTakedowns) {
251
254
  takedownRef: safeTakedownRef(entry),
252
255
  };
253
256
  }
254
- const emptySiteStandardRecords = () => ({
255
- documents: new HydrationMap(),
256
- publications: new HydrationMap(),
257
- });
258
257
  const siteStandardKind = (uri) => {
259
258
  const parsed = parseAtUriString(uri);
260
259
  if (!parsed.success)
@@ -277,82 +276,101 @@ const matchRecordInfo = (schema, info) => info && schema.$matches(info.record, {
277
276
  ? { ...info, record: info.record }
278
277
  : null;
279
278
  /**
280
- * Store a generic record in the map matching its collection. Records failing
281
- * Lexicon validation are stored as null.
279
+ * Select one pinned embed root. Legacy publication-first pairs may put their
280
+ * document second; no other authored refs participate in hydration.
282
281
  */
283
- const setSiteStandardRecord = (out, uri, key, info) => {
284
- switch (siteStandardKind(uri)) {
285
- case 'documents':
286
- out.documents.set(key, matchRecordInfo(site.standard.document.main, info));
287
- break;
288
- case 'publications':
289
- out.publications.set(key, matchRecordInfo(site.standard.publication.main, info));
290
- break;
282
+ export function getExternalRootRef(refs) {
283
+ let root = refs?.[0];
284
+ if (!root)
285
+ return undefined;
286
+ if (siteStandardKind(root.uri) === 'publications') {
287
+ const second = refs?.[1];
288
+ if (second && siteStandardKind(second.uri) === 'documents')
289
+ root = second;
291
290
  }
292
- };
293
- /**
294
- * Read-path resolution: caller pinned a set of `(uri, cid)` strongRefs in
295
- * the post at write time, and we honor those exact versions. Any pair
296
- * that doesn't structurally agree is rejected, so downstream callers can
297
- * trust the returned shape.
298
- *
299
- * Pairing rules:
300
- * - Both slots referenced: `doc.site` must equal `publication.ref.uri`,
301
- * else both come back `undefined`.
302
- * - Doc with at-uri `site` referenced but no matching publication ref:
303
- * reject the whole pairing (doc claims a publication that should have
304
- * been pinned, but wasn't).
305
- * - Loose doc (web-URL `site`) referenced: publication stays `undefined`.
306
- * - Only a publication referenced: document stays `undefined`.
307
- *
308
- * Each returned slot carries the matching `ref` so callers can recover
309
- * the owner DID for blob-cdn URL building, etc.
310
- */
311
- export const getSiteStandardRecordsFromHydrationMapsByRefs = (associatedRefs, documents, publications) => {
312
- if (!associatedRefs?.length) {
313
- return { document: undefined, publication: undefined };
291
+ return isHydratableAssociatedRef(root) ? root : undefined;
292
+ }
293
+ /** Select a pinned Standard.site root and its derived publication, if needed. */
294
+ export function getSiteStandardRecordsFromRefs(associatedRefs, records, dependencies) {
295
+ const empty = { document: undefined, publication: undefined };
296
+ const ref = getExternalRootRef(associatedRefs);
297
+ if (!ref)
298
+ return empty;
299
+ const info = records?.get(genericRecordKey(ref));
300
+ if (siteStandardKind(ref.uri) === 'publications') {
301
+ const publication = matchRecordInfo(site.standard.publication.main, info);
302
+ return publication
303
+ ? { document: undefined, publication: { ref, info: publication } }
304
+ : empty;
314
305
  }
315
- // Resolve each ref against the hydration maps, taking the first hit on
316
- // each side.
317
- let document;
318
- let publication;
319
- for (const ref of associatedRefs) {
320
- const key = genericRecordKey(ref);
321
- if (!document) {
322
- const hit = documents?.get(key);
323
- if (hit)
324
- document = { ref, info: hit };
325
- }
326
- if (!publication) {
327
- const hit = publications?.get(key);
328
- if (hit)
329
- publication = { ref, info: hit };
330
- }
331
- if (document && publication)
332
- break;
306
+ if (siteStandardKind(ref.uri) !== 'documents')
307
+ return empty;
308
+ const document = matchRecordInfo(site.standard.document.main, info);
309
+ if (!document)
310
+ return empty;
311
+ const documentSelection = { ref, info: document };
312
+ const docSite = document.record.site;
313
+ if (!docSite.startsWith('at://')) {
314
+ return { document: documentSelection, publication: undefined };
333
315
  }
334
- // Both refs resolved: enforce that the doc's `site` actually points at
335
- // the supplied publication. Mismatch means the post was misconstructed
336
- // (or tampered with), so reject the whole pairing.
337
- if (document && publication) {
338
- if (document.info.record.site !== publication.ref.uri) {
339
- hydrationLogger.warn({
340
- documentUri: document.ref.uri,
341
- documentSite: document.info.record.site,
342
- publicationUri: publication.ref.uri,
343
- }, 'site.standard byRefs lookup failed: doc.site does not match hydrated publication.uri');
344
- return { document: undefined, publication: undefined };
345
- }
316
+ const uri = recordUriOf(docSite, site.standard.publication.$type);
317
+ if (!uri)
318
+ return empty;
319
+ const publication = matchRecordInfo(site.standard.publication.main, dependencies?.get(uri));
320
+ if (!publication)
321
+ return empty;
322
+ return {
323
+ document: documentSelection,
324
+ publication: { ref: { uri, cid: publication.cid }, info: publication },
325
+ };
326
+ }
327
+ const externalAssociatedRefs = (post) => {
328
+ const embed = post?.embed;
329
+ if (!embed)
330
+ return [];
331
+ if (isExternalEmbedType(embed)) {
332
+ return embed.external.associatedRefs ?? [];
346
333
  }
347
- // Doc with at-uri `site` but no publication: the post should have
348
- // pinned the publication too. Treat as misconstructed.
349
- if (document && !publication) {
350
- const site = document.info.record.site;
351
- if (site && site.startsWith('at://')) {
352
- hydrationLogger.warn({ documentUri: document.ref.uri, documentSite: site }, 'site.standard byRefs lookup failed: document.site is AT URI but no matching publication was hydrated');
353
- return { document: undefined, publication: undefined };
334
+ if (isRecordWithMediaType(embed) && isExternalEmbedType(embed.media)) {
335
+ return embed.media.external.associatedRefs ?? [];
336
+ }
337
+ return [];
338
+ };
339
+ /**
340
+ * An exact ref needs a nonempty CID and a complete record URI in a DID repo,
341
+ * so malformed refs are skipped instead of becoming latest lookups.
342
+ */
343
+ const isHydratableAssociatedRef = (ref) => {
344
+ if (!ref.cid)
345
+ return false;
346
+ const parsed = parseAtUriString(ref.uri);
347
+ if (!parsed.success)
348
+ return false;
349
+ const { authority, collection, rkey, query, hash } = parsed.value;
350
+ return (isDidString(authority) &&
351
+ !!collection &&
352
+ !!rkey &&
353
+ query === undefined &&
354
+ hash === undefined);
355
+ };
356
+ /** Collect one root per post across all layers, deduped by exact ref. */
357
+ export const externalAssociatedRefsFromPosts = (...postLayers) => {
358
+ const seen = new Set();
359
+ const out = [];
360
+ for (const layer of postLayers) {
361
+ for (const item of layer.values()) {
362
+ if (!item)
363
+ continue;
364
+ const ref = getExternalRootRef(externalAssociatedRefs(item.record));
365
+ if (!ref)
366
+ continue;
367
+ const key = genericRecordKey(ref);
368
+ if (seen.has(key))
369
+ continue;
370
+ seen.add(key);
371
+ out.push({ uri: ref.uri, cid: ref.cid });
354
372
  }
355
373
  }
356
- return { document, publication };
374
+ return out;
357
375
  };
358
376
  //# 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 { performance } from 'node:perf_hooks'\nimport { chunkArray } from '@atproto/common'\nimport {\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 type HydrationXrpcEndpoint,\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 * Entries per generic record RPC. The dataplane rejects larger URI lookups;\n * exact-ref lookups use the same bound defensively.\n */\n static readonly MAX_RECORDS_PER_REQUEST = 100\n\n constructor(public dataplane: DataPlaneClient) {}\n\n /**\n * Fetch exact record versions; unavailable records are represented by null.\n * Large inputs are fetched in sequential bounded requests; any failed request\n * rejects the whole call.\n */\n async getRecordsByRef(\n refs: Required<ItemRef>[],\n includeTakedowns = false,\n ): Promise<ExternalRecordsByRef> {\n const map: ExternalRecordsByRef = new HydrationMap()\n for (const chunk of chunkArray(\n refs,\n ExternalHydrator.MAX_RECORDS_PER_REQUEST,\n )) {\n const res = await this.dataplane.getRecordsByRef({ refs: chunk })\n // Results are positional within each request.\n for (let i = 0; i < chunk.length; i++) {\n map.set(\n genericRecordKey(chunk[i]),\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\n }\n }\n return map\n }\n\n /**\n * Fetch the latest indexed versions without collection-specific validation.\n * Large inputs are fetched in sequential bounded requests; any failed request\n * rejects the whole call.\n */\n async getRecordsByURI(\n uris: AtUriString[],\n includeTakedowns = false,\n ): Promise<ExternalRecords> {\n const map: ExternalRecords = new HydrationMap()\n for (const chunk of chunkArray(\n uris,\n ExternalHydrator.MAX_RECORDS_PER_REQUEST,\n )) {\n const res = await this.dataplane.getRecordsByURI({ uris: chunk })\n // Results are positional within each request.\n for (let i = 0; i < chunk.length; i++) {\n map.set(\n chunk[i],\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\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; `partial`\n * records a recovered best-effort dependency failure.\n */\nexport type ExternalHydrationTracker = ExternalHydrationWork & {\n capped: boolean\n partial: boolean\n /**\n * Internal: set by the traversal's first dependency discovery, whose refs\n * are its roots.\n */\n rootsCounted: 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, with the\n * context's XRPC endpoint (`'unknown'` if unset) and the traversal's wall time. A\n * returned traversal is `capped` if it hit the pass limit, else `partial` if\n * it recovered from a dependency failure. Owners that completed without\n * scheduling a batch did no work and are not reported; other outcomes always\n * are.\n */\nexport async function trackExternalHydration<T>(\n root: ExternalHydrationRoot,\n xrpcEndpoint: HydrationXrpcEndpoint | undefined,\n hydrationMetrics: ExternalHydrationTracker | undefined,\n fn: (hydrationMetrics: ExternalHydrationTracker) => Promise<T>,\n): Promise<T> {\n if (hydrationMetrics) return fn(hydrationMetrics)\n const owned: ExternalHydrationTracker = {\n recordLookups: 0,\n batches: 0,\n maxPass: 0,\n roots: 0,\n rootsResolved: 0,\n dependencies: 0,\n dependenciesResolved: 0,\n capped: false,\n partial: false,\n rootsCounted: false,\n }\n let outcome: ExternalHydrationOutcome = 'failed'\n const start = performance.now()\n try {\n const state = await fn(owned)\n outcome = owned.capped ? 'capped' : owned.partial ? 'partial' : 'completed'\n return state\n } finally {\n if (owned.batches || outcome !== 'completed') {\n events.externalHydrationTraversal({\n xrpcEndpoint: xrpcEndpoint ?? 'unknown',\n root,\n outcome,\n durationMs: performance.now() - start,\n recordLookups: owned.recordLookups,\n batches: owned.batches,\n maxPass: owned.maxPass,\n roots: owned.roots,\n rootsResolved: owned.rootsResolved,\n dependencies: owned.dependencies,\n dependenciesResolved: owned.dependenciesResolved,\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"]}
1
+ {"version":3,"file":"external.js","sourceRoot":"","sources":["../../src/hydration/external.ts"],"names":[],"mappings":"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","sourcesContent":["import { performance } from 'node:perf_hooks'\nimport { chunkArray } from '@atproto/common'\nimport {\n type AtUriString,\n type DidString,\n type InferInput,\n type NsidString,\n type RecordSchema,\n type TypedLexMap,\n isDidString,\n isTypedLexMap,\n lexParseJsonBytes,\n} from '@atproto/lex'\nimport { parseAtUriString } from '@atproto/syntax'\nimport type { DataPlaneClient } from '../data-plane/client/index.js'\nimport { site, social } from '../lexicons/index.js'\nimport {\n type RecordLookupResult,\n RecordLookupStatus,\n} from '../proto/bsky_pb.js'\nimport {\n type ExternalHydrationOutcome,\n type ExternalHydrationRoot,\n type ExternalHydrationWork,\n type HydrationXrpcEndpoint,\n events,\n} from '../telemetry/events.js'\nimport { recordUriOf, uriToDid } from '../util/uris.js'\nimport {\n type SiteStandardDocumentRecord,\n type SiteStandardPublicationRecord,\n isExternalEmbedType,\n isRecordWithMediaType,\n} from '../views/types.js'\nimport type { Actors } from './actor.js'\nimport type { Post, Posts } from './feed.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\nexport type ExternalHydrationLevel = 'basic' | 'detailed'\n\n/**\n * Options for external hydration traversals. `hydration` picks one level for\n * the whole traversal (default `'detailed'`): `'basic'` hydrates renderable\n * content, moderation and aggregate backlink counts; `'detailed'` also samples\n * social-preview backlinks and hydrates their records and participants. The\n * remaining fields are traversal state shared by nested passes.\n */\nexport type ExternalHydrationOptions = {\n hydration?: ExternalHydrationLevel\n seenRecordKeys?: Set<string>\n hydrationPass?: number\n hydrationMetrics?: ExternalHydrationTracker\n}\n\n/**\n * Per-collection sample limits. Basic hydration skips social previews,\n * but keeps gallery items. Direct publication/photo references are singular.\n */\nexport const EXTERNAL_HYDRATION_LIMITS = {\n [site.standard.document.$type]: { recommendationPreviews: 3 },\n [site.standard.publication.$type]: { subscriberPreviews: 3 },\n [social.grain.gallery.$type]: { items: 10, favoritePreviews: 3 },\n} as const\n\n/** Maximum in-flight backlink sample RPCs, not a dependency-count limit. */\nexport const MAX_CONCURRENT_BACKLINK_REQUESTS = 8\n/** Maximum logical batches per traversal, counting the root as pass 1. */\nexport const MAX_EXTERNAL_HYDRATION_PASSES = 8\n\nexport class ExternalHydrator {\n /**\n * Entries per generic record RPC. The dataplane rejects larger URI lookups;\n * exact-ref lookups use the same bound defensively.\n */\n static readonly MAX_RECORDS_PER_REQUEST = 100\n /**\n * Target URIs per backlink-count RPC. The dataplane requires between 1 and\n * 100; this is a separate limit from `MAX_RECORDS_PER_REQUEST`.\n */\n static readonly MAX_BACKLINK_COUNT_TARGETS_PER_REQUEST = 100\n\n constructor(public dataplane: DataPlaneClient) {}\n\n /**\n * Fetch exact record versions; unavailable records are represented by null.\n * Large inputs are fetched in sequential bounded requests; any failed request\n * rejects the whole call.\n */\n async getRecordsByRef(\n refs: Required<ItemRef>[],\n includeTakedowns = false,\n ): Promise<ExternalRecordsByRef> {\n const map: ExternalRecordsByRef = new HydrationMap()\n for (const chunk of chunkArray(\n refs,\n ExternalHydrator.MAX_RECORDS_PER_REQUEST,\n )) {\n const res = await this.dataplane.getRecordsByRef({ refs: chunk })\n // Results are positional within each request.\n for (let i = 0; i < chunk.length; i++) {\n map.set(\n genericRecordKey(chunk[i]),\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\n }\n }\n return map\n }\n\n /**\n * Fetch the latest indexed versions without collection-specific validation.\n * Large inputs are fetched in sequential bounded requests; any failed request\n * rejects the whole call.\n */\n async getRecordsByURI(\n uris: AtUriString[],\n includeTakedowns = false,\n ): Promise<ExternalRecords> {\n const map: ExternalRecords = new HydrationMap()\n for (const chunk of chunkArray(\n uris,\n ExternalHydrator.MAX_RECORDS_PER_REQUEST,\n )) {\n const res = await this.dataplane.getRecordsByURI({ uris: chunk })\n // Results are positional within each request.\n for (let i = 0; i < chunk.length; i++) {\n map.set(\n chunk[i],\n parseGenericRecord(res.results[i], includeTakedowns) ?? null,\n )\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 /**\n * Fetch source-record counts, optionally restricted to one collection. Large\n * inputs are fetched in sequential bounded requests; any failed request\n * rejects the whole call.\n */\n async getAtmosphereBacklinkCounts(\n targetUris: AtUriString[],\n collection?: NsidString,\n ): Promise<ExternalRecordBacklinkCounts> {\n const map: ExternalRecordBacklinkCounts = new HydrationMap()\n for (const chunk of chunkArray(\n targetUris,\n ExternalHydrator.MAX_BACKLINK_COUNT_TARGETS_PER_REQUEST,\n )) {\n const res = await this.dataplane.getAtmosphereBacklinkCounts({\n targetUris: chunk,\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 }\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/**\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; `partial`\n * records a recovered best-effort dependency failure.\n */\nexport type ExternalHydrationTracker = ExternalHydrationWork & {\n capped: boolean\n partial: boolean\n /**\n * Internal: set by the traversal's first dependency discovery, whose refs\n * are its roots.\n */\n rootsCounted: 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, with the\n * context's XRPC endpoint (`'unknown'` if unset) and the traversal's wall time. A\n * returned traversal is `capped` if it hit the pass limit, else `partial` if\n * it recovered from a dependency failure. Owners that completed report when\n * they scheduled a batch or inspected roots (even prehydrated or unavailable\n * ones); only genuinely empty successful calls are not reported. Other\n * outcomes always are.\n */\nexport async function trackExternalHydration<T>(\n root: ExternalHydrationRoot,\n xrpcEndpoint: HydrationXrpcEndpoint | undefined,\n hydrationMetrics: ExternalHydrationTracker | undefined,\n fn: (hydrationMetrics: ExternalHydrationTracker) => Promise<T>,\n): Promise<T> {\n if (hydrationMetrics) return fn(hydrationMetrics)\n const owned: ExternalHydrationTracker = {\n recordLookups: 0,\n batches: 0,\n maxPass: 0,\n roots: 0,\n rootsResolved: 0,\n dependencies: 0,\n dependenciesResolved: 0,\n capped: false,\n partial: false,\n rootsCounted: false,\n }\n let outcome: ExternalHydrationOutcome = 'failed'\n const start = performance.now()\n try {\n const state = await fn(owned)\n outcome = owned.capped ? 'capped' : owned.partial ? 'partial' : 'completed'\n return state\n } finally {\n if (owned.batches > 0 || owned.roots > 0 || outcome !== 'completed') {\n events.externalHydrationTraversal({\n xrpcEndpoint: xrpcEndpoint ?? 'unknown',\n root,\n outcome,\n durationMs: performance.now() - start,\n recordLookups: owned.recordLookups,\n batches: owned.batches,\n maxPass: owned.maxPass,\n roots: owned.roots,\n rootsResolved: owned.rootsResolved,\n dependencies: owned.dependencies,\n dependenciesResolved: owned.dependenciesResolved,\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 siteStandardKind = (\n uri: string,\n): 'documents' | 'publications' | 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\nexport type AssociatedSiteStandardRecord<T> = {\n ref: { uri: AtUriString; cid: string }\n info: T\n}\n\n/**\n * Select one pinned embed root. Legacy publication-first pairs may put their\n * document second; no other authored refs participate in hydration.\n */\nexport function getExternalRootRef(\n refs: readonly Required<ItemRef>[] | undefined,\n): Required<ItemRef> | undefined {\n let root = refs?.[0]\n if (!root) return undefined\n if (siteStandardKind(root.uri) === 'publications') {\n const second = refs?.[1]\n if (second && siteStandardKind(second.uri) === 'documents') root = second\n }\n return isHydratableAssociatedRef(root) ? root : undefined\n}\n\n/** Select a pinned Standard.site root and its derived publication, if needed. */\nexport function getSiteStandardRecordsFromRefs(\n associatedRefs: readonly Required<ItemRef>[] | undefined,\n records: ExternalRecordsByRef | undefined,\n dependencies?: ExternalRecords,\n): {\n document: AssociatedSiteStandardRecord<SiteStandardDocument> | undefined\n publication: AssociatedSiteStandardRecord<SiteStandardPublication> | undefined\n} {\n const empty = { document: undefined, publication: undefined }\n const ref = getExternalRootRef(associatedRefs)\n if (!ref) return empty\n const info = records?.get(genericRecordKey(ref))\n if (siteStandardKind(ref.uri) === 'publications') {\n const publication = matchRecordInfo(site.standard.publication.main, info)\n return publication\n ? { document: undefined, publication: { ref, info: publication } }\n : empty\n }\n if (siteStandardKind(ref.uri) !== 'documents') return empty\n const document = matchRecordInfo(site.standard.document.main, info)\n if (!document) return empty\n const documentSelection = { ref, info: document }\n const docSite = document.record.site\n if (!docSite.startsWith('at://')) {\n return { document: documentSelection, publication: undefined }\n }\n const uri = recordUriOf(docSite, site.standard.publication.$type)\n if (!uri) return empty\n const publication = matchRecordInfo(\n site.standard.publication.main,\n dependencies?.get(uri),\n )\n if (!publication) return empty\n return {\n document: documentSelection,\n publication: { ref: { uri, cid: publication.cid }, info: publication },\n }\n}\n\nconst externalAssociatedRefs = (\n post: Post['record'],\n): { uri: AtUriString; cid: string }[] => {\n const embed = post?.embed\n if (!embed) return []\n if (isExternalEmbedType(embed)) {\n return embed.external.associatedRefs ?? []\n }\n if (isRecordWithMediaType(embed) && isExternalEmbedType(embed.media)) {\n return embed.media.external.associatedRefs ?? []\n }\n return []\n}\n\n/**\n * An exact ref needs a nonempty CID and a complete record URI in a DID repo,\n * so malformed refs are skipped instead of becoming latest lookups.\n */\nconst isHydratableAssociatedRef = (ref: {\n uri: string\n cid: string\n}): boolean => {\n if (!ref.cid) return false\n const parsed = parseAtUriString(ref.uri)\n if (!parsed.success) return false\n const { authority, collection, rkey, query, hash } = parsed.value\n return (\n isDidString(authority) &&\n !!collection &&\n !!rkey &&\n query === undefined &&\n hash === undefined\n )\n}\n\n/** Collect one root per post across all layers, deduped by exact ref. */\nexport const externalAssociatedRefsFromPosts = (\n ...postLayers: Posts[]\n): Required<ItemRef>[] => {\n const seen = new Set<string>()\n const out: Required<ItemRef>[] = []\n for (const layer of postLayers) {\n for (const item of layer.values()) {\n if (!item) continue\n const ref = getExternalRootRef(externalAssociatedRefs(item.record))\n if (!ref) continue\n const key = genericRecordKey(ref)\n if (seen.has(key)) continue\n seen.add(key)\n out.push({ uri: ref.uri, cid: ref.cid })\n }\n }\n return out\n}\n"]}
@@ -7,7 +7,7 @@ import type { BookmarkInfo, Notification } from '../proto/bsky_pb.js';
7
7
  import { type HydrationXrpcEndpoint } from '../telemetry/events.js';
8
8
  import type { ParsedLabelers } from '../util.js';
9
9
  import { type ActivitySubscriptionStates, ActorHydrator, type Actors, type KnownFollowersStates, type KnownLikersStates, type ProfileAggs, type ProfileLinks, type ProfileViewerStates } from './actor.js';
10
- import { type ExternalHydrationTracker, ExternalHydrator, type ExternalRecordBacklinkCounts, type ExternalRecordBacklinks, type ExternalRecords, type ExternalRecordsByRef, type SiteStandardDocuments, type SiteStandardPublications } from './external.js';
10
+ import { type ExternalHydrationOptions, ExternalHydrator, type ExternalRecordBacklinkCounts, type ExternalRecordBacklinks, type ExternalRecords, type ExternalRecordsByRef } from './external.js';
11
11
  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';
12
12
  import { type Follows, GraphHydrator, type ListAggs, type ListItems, type ListMembershipStates, type ListViewerStates, type Lists, type StarterPackAggs, type StarterPacks, type Verifications } from './graph.js';
13
13
  import { LabelHydrator, type LabelerAggs, type LabelerViewerStates, type Labelers, Labels } from './label.js';
@@ -87,8 +87,6 @@ export type HydrationState = {
87
87
  /** Available backlink source URIs per target, potentially from a partial page. */
88
88
  externalRecordBacklinks?: ExternalRecordBacklinks;
89
89
  externalRecordBacklinkCounts?: ExternalRecordBacklinkCounts;
90
- siteStandardDocuments?: SiteStandardDocuments;
91
- siteStandardPublications?: SiteStandardPublications;
92
90
  };
93
91
  type HydrateKnownLikersOptions = {
94
92
  subjectUris: AtUriString[];
@@ -171,15 +169,16 @@ export declare class Hydrator {
171
169
  * generic batch within the traversal (the root batch is pass 1); nested
172
170
  * batches continue the count. Nested passes share the caller's
173
171
  * `hydrationMetrics` tracker; without one, this call owns the traversal and
174
- * reports its totals.
172
+ * reports its totals. `options.hydration` (default `'detailed'`) applies to
173
+ * the whole traversal and is propagated to every nested pass.
175
174
  */
176
- hydrateEmbedExternalViewFromUris(uris: AtUriString[], ctx: HydrateCtx, seenRecordKeys?: Set<string>, hydrationPass?: number, hydrationMetrics?: ExternalHydrationTracker): Promise<HydrationState>;
175
+ hydrateEmbedExternalViewFromUris(uris: AtUriString[], ctx: HydrateCtx, options?: ExternalHydrationOptions): Promise<HydrationState>;
177
176
  /**
178
177
  * Like `hydrateEmbedExternalViewFromUris`, but for exact record versions
179
178
  * pinned by strong refs. Roots land only in `externalRecordsByRef`; their
180
179
  * URI dependencies are hydrated as latest versions by the URI path.
181
180
  */
182
- hydrateEmbedExternalViewFromRefs(refs: Required<ItemRef>[], ctx: HydrateCtx, seenRecordKeys?: Set<string>, hydrationPass?: number, hydrationMetrics?: ExternalHydrationTracker): Promise<HydrationState>;
181
+ hydrateEmbedExternalViewFromRefs(refs: Required<ItemRef>[], ctx: HydrateCtx, options?: ExternalHydrationOptions): Promise<HydrationState>;
183
182
  private hydrateEmbedExternalView;
184
183
  /**
185
184
  * Discover view dependencies by URI collection and hydrate new URIs in a batch.
@@ -194,9 +193,12 @@ export declare class Hydrator {
194
193
  * `hydrationPass` is the number of the generic batch that produced `state`
195
194
  * (1-based, default 1 for prehydrated state, which is treated as the root
196
195
  * batch); the next nested batch is `hydrationPass + 1`. `hydrationMetrics`
197
- * is shared as in `hydrateEmbedExternalViewFromUris`.
196
+ * is shared as in `hydrateEmbedExternalViewFromUris`. `options.hydration`
197
+ * (default `'detailed'`) decides, per collection, whether social-preview
198
+ * samples are scheduled; backlink counts and content dependencies are
199
+ * discovered at both levels.
198
200
  */
199
- hydrateExternalViewDependencies(state: HydrationState, refs: ItemRef[], ctx: HydrateCtx, seenRecordKeys?: Set<string>, hydrationPass?: number, hydrationMetrics?: ExternalHydrationTracker): Promise<HydrationState>;
201
+ hydrateExternalViewDependencies(state: HydrationState, refs: ItemRef[], ctx: HydrateCtx, options?: ExternalHydrationOptions): Promise<HydrationState>;
200
202
  private discoverExternalViewDependencies;
201
203
  hydrateThreadPosts(refs: ItemRef[], ctx: HydrateCtx, options?: Pick<HydratePostsOptions, 'knownLikers'>): Promise<HydrationState>;
202
204
  private hydrateKnownLikers;
@@ -1 +1 @@
1
- {"version":3,"file":"hydrator.d.ts","sourceRoot":"","sources":["../../src/hydration/hydrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hydrator.d.ts","sourceRoot":"","sources":["../../src/hydration/hydrator.ts"],"names":[],"mappings":"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"}