@atproto/bsky 0.1.0 → 0.1.3
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 +43 -0
- package/dist/api/app/bsky/actor/getSuggestions.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/getSuggestions.js +9 -3
- package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
- package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getFeed.js +44 -15
- package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +7 -3
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +13 -4
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js +12 -4
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js +10 -3
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js +13 -4
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js +18 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js +17 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js +18 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js +18 -0
- package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js.map +1 -1
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -1
- package/dist/data-plane/server/routes/atmosphere.d.ts +5 -0
- package/dist/data-plane/server/routes/atmosphere.d.ts.map +1 -0
- package/dist/data-plane/server/routes/atmosphere.js +24 -0
- package/dist/data-plane/server/routes/atmosphere.js.map +1 -0
- package/dist/data-plane/server/routes/index.js +2 -2
- package/dist/data-plane/server/routes/index.js.map +1 -1
- package/dist/feature-gates/gates.d.ts +10 -0
- package/dist/feature-gates/gates.d.ts.map +1 -1
- package/dist/feature-gates/gates.js +10 -0
- package/dist/feature-gates/gates.js.map +1 -1
- package/dist/feature-gates/index.js +2 -2
- package/dist/feature-gates/index.js.map +1 -1
- package/dist/hydration/external.d.ts +65 -2
- package/dist/hydration/external.d.ts.map +1 -1
- package/dist/hydration/external.js +220 -29
- package/dist/hydration/external.js.map +1 -1
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +7 -7
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.d.ts +2 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.js +1 -0
- package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.js.map +1 -1
- package/dist/lexicons/tools/ozone/report/defs.defs.d.ts +17 -1
- package/dist/lexicons/tools/ozone/report/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/tools/ozone/report/defs.defs.js +10 -0
- package/dist/lexicons/tools/ozone/report/defs.defs.js.map +1 -1
- package/dist/proto/bsky_connect.d.ts +57 -21
- package/dist/proto/bsky_connect.d.ts.map +1 -1
- package/dist/proto/bsky_connect.js +57 -21
- package/dist/proto/bsky_connect.js.map +1 -1
- package/dist/proto/bsky_pb.d.ts +361 -72
- package/dist/proto/bsky_pb.d.ts.map +1 -1
- package/dist/proto/bsky_pb.js +529 -70
- package/dist/proto/bsky_pb.js.map +1 -1
- package/dist/util/standard-site.d.ts +0 -12
- package/dist/util/standard-site.d.ts.map +1 -1
- package/dist/util/standard-site.js +0 -14
- package/dist/util/standard-site.js.map +1 -1
- package/package.json +8 -8
- package/dist/data-plane/server/routes/site-standard.d.ts +0 -6
- package/dist/data-plane/server/routes/site-standard.d.ts.map +0 -1
- package/dist/data-plane/server/routes/site-standard.js +0 -9
- package/dist/data-plane/server/routes/site-standard.js.map +0 -1
|
@@ -1,46 +1,237 @@
|
|
|
1
|
+
import { isTypedLexMap, lexParseJsonBytes, } from '@atproto/lex';
|
|
2
|
+
import { parseAtUriString } from '@atproto/syntax';
|
|
1
3
|
import { site } from '../lexicons/index.js';
|
|
2
4
|
import { hydrationLogger } from '../logger.js';
|
|
3
|
-
import {
|
|
4
|
-
import { HydrationMap,
|
|
5
|
+
import { RecordLookupStatus, } from '../proto/bsky_pb.js';
|
|
6
|
+
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
|
+
}
|
|
5
24
|
export class ExternalHydrator {
|
|
6
25
|
constructor(dataplane) {
|
|
7
26
|
this.dataplane = dataplane;
|
|
8
27
|
}
|
|
9
|
-
|
|
28
|
+
/** Fetch exact record versions; unavailable records are represented by null. */
|
|
29
|
+
async getRecordsByRef(refs, includeTakedowns = false) {
|
|
30
|
+
const map = new HydrationMap();
|
|
10
31
|
if (!refs.length)
|
|
11
|
-
return
|
|
12
|
-
const res = await this.dataplane.
|
|
13
|
-
|
|
32
|
+
return map;
|
|
33
|
+
const res = await this.dataplane.getRecordsByRef({ refs });
|
|
34
|
+
for (let i = 0; i < refs.length; i++) {
|
|
35
|
+
const { uri, cid } = refs[i];
|
|
36
|
+
map.set(genericRecordKey(uri, cid), parseGenericRecord(res.results[i], includeTakedowns) ?? null);
|
|
37
|
+
}
|
|
38
|
+
return map;
|
|
39
|
+
}
|
|
40
|
+
/** Fetch the latest indexed versions without collection-specific validation. */
|
|
41
|
+
async getRecordsByURI(uris, includeTakedowns = false) {
|
|
42
|
+
const map = new HydrationMap();
|
|
43
|
+
if (!uris.length)
|
|
44
|
+
return map;
|
|
45
|
+
const res = await this.dataplane.getRecordsByURI({ uris });
|
|
46
|
+
for (let i = 0; i < uris.length; i++) {
|
|
47
|
+
map.set(uris[i], parseGenericRecord(res.results[i], includeTakedowns) ?? null);
|
|
48
|
+
}
|
|
49
|
+
return map;
|
|
50
|
+
}
|
|
51
|
+
/** Fetch a page of activity refs for subsequent generic record hydration. */
|
|
52
|
+
async getAtmosphereTimeline(viewerDid, opts = {}) {
|
|
53
|
+
const res = await this.dataplane.getAtmosphereTimeline({
|
|
54
|
+
viewerDid,
|
|
55
|
+
...opts,
|
|
14
56
|
});
|
|
15
|
-
return
|
|
57
|
+
return {
|
|
58
|
+
items: res.items.map((item) => ({
|
|
59
|
+
uri: item.uri,
|
|
60
|
+
sortedAt: parseDate(item.sortedAt) ?? new Date(0),
|
|
61
|
+
})),
|
|
62
|
+
cursor: res.cursor || undefined,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** Fetch source-record counts, optionally restricted to one collection. */
|
|
66
|
+
async getAtmosphereBacklinkCounts(targetUris, collection) {
|
|
67
|
+
const map = new HydrationMap();
|
|
68
|
+
if (!targetUris.length)
|
|
69
|
+
return map;
|
|
70
|
+
const res = await this.dataplane.getAtmosphereBacklinkCounts({
|
|
71
|
+
targetUris,
|
|
72
|
+
collection,
|
|
73
|
+
});
|
|
74
|
+
for (const result of res.results) {
|
|
75
|
+
map.set(result.targetUri, Object.fromEntries(Object.entries(result.counts).map(([nsid, count]) => [
|
|
76
|
+
nsid,
|
|
77
|
+
Number(count),
|
|
78
|
+
])));
|
|
79
|
+
}
|
|
80
|
+
return map;
|
|
81
|
+
}
|
|
82
|
+
/** Fetch a page of source records linking to a target. */
|
|
83
|
+
async getAtmosphereBacklinks(targetUri, collection, opts = {}) {
|
|
84
|
+
const res = await this.dataplane.getAtmosphereBacklinks({
|
|
85
|
+
targetUri,
|
|
86
|
+
collection,
|
|
87
|
+
...opts,
|
|
88
|
+
});
|
|
89
|
+
return {
|
|
90
|
+
backlinks: res.backlinks.map((backlink) => ({
|
|
91
|
+
uri: backlink.uri,
|
|
92
|
+
sortedAt: parseDate(backlink.sortedAt) ?? new Date(0),
|
|
93
|
+
})),
|
|
94
|
+
cursor: res.cursor || undefined,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/** Fetch an actor's links per target, retaining the batch truncation flag. */
|
|
98
|
+
async getAtmosphereBacklinksByActor(targetUris, actorDid, collection) {
|
|
99
|
+
const backlinks = new HydrationMap();
|
|
100
|
+
if (!targetUris.length)
|
|
101
|
+
return { backlinks, truncated: false };
|
|
102
|
+
const res = await this.dataplane.getAtmosphereBacklinksByActor({
|
|
103
|
+
targetUris,
|
|
104
|
+
actorDid,
|
|
105
|
+
collection,
|
|
106
|
+
});
|
|
107
|
+
for (const result of res.results) {
|
|
108
|
+
backlinks.set(result.targetUri, result.uris);
|
|
109
|
+
}
|
|
110
|
+
return { backlinks, truncated: res.truncated };
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Fetch exact `site.standard.{document,publication}` versions. Does NOT
|
|
114
|
+
* resolve a document's publication; callers must pin it explicitly.
|
|
115
|
+
*/
|
|
116
|
+
async getSiteStandardRecordsByRef(refs, includeTakedowns = false) {
|
|
117
|
+
const ssRefs = refs.filter((ref) => !!ref.cid && siteStandardKind(ref.uri) !== undefined);
|
|
118
|
+
const out = emptySiteStandardRecords();
|
|
119
|
+
if (!ssRefs.length)
|
|
120
|
+
return out;
|
|
121
|
+
const records = await this.getRecordsByRef(ssRefs, includeTakedowns);
|
|
122
|
+
for (const [key, info] of records) {
|
|
123
|
+
setSiteStandardRecord(out, parseGenericRecordKey(key).uri, key, info);
|
|
124
|
+
}
|
|
125
|
+
return out;
|
|
16
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Fetch the latest `site.standard.{document,publication}` versions. The
|
|
129
|
+
* generic record lookup does not follow references, so publications named
|
|
130
|
+
* by the `site` field of the hydrated documents are fetched in a second
|
|
131
|
+
* call.
|
|
132
|
+
*/
|
|
17
133
|
async getSiteStandardRecordsByURI(uris, includeTakedowns = false) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
134
|
+
const requested = [...new Set(uris.filter((u) => siteStandardKind(u)))];
|
|
135
|
+
const out = emptySiteStandardRecords();
|
|
136
|
+
if (!requested.length)
|
|
137
|
+
return out;
|
|
138
|
+
await this.addSiteStandardRecordsByURI(out, requested, includeTakedowns);
|
|
139
|
+
// Publications referenced by documents but not already requested.
|
|
140
|
+
const requestedSet = new Set(requested);
|
|
141
|
+
const pubUris = new Set();
|
|
142
|
+
for (const doc of out.documents.values()) {
|
|
143
|
+
const pubUri = doc && publicationUriFromSite(doc.record.site);
|
|
144
|
+
if (pubUri && !requestedSet.has(pubUri))
|
|
145
|
+
pubUris.add(pubUri);
|
|
146
|
+
}
|
|
147
|
+
if (pubUris.size) {
|
|
148
|
+
await this.addSiteStandardRecordsByURI(out, [...pubUris], includeTakedowns);
|
|
149
|
+
}
|
|
150
|
+
return out;
|
|
151
|
+
}
|
|
152
|
+
async addSiteStandardRecordsByURI(out, uris, includeTakedowns) {
|
|
153
|
+
const records = await this.getRecordsByURI(uris, includeTakedowns);
|
|
154
|
+
for (const [uri, info] of records) {
|
|
155
|
+
// Unavailable records have no CID to key on, so they are left out.
|
|
156
|
+
if (!info)
|
|
157
|
+
continue;
|
|
158
|
+
setSiteStandardRecord(out, uri, genericRecordKey(uri, info.cid), info);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function parseGenericRecord(result, includeTakedowns) {
|
|
163
|
+
if (result?.status !== RecordLookupStatus.FOUND &&
|
|
164
|
+
!(includeTakedowns && result?.status === RecordLookupStatus.TAKEN_DOWN)) {
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
const entry = result.record;
|
|
168
|
+
if (!entry?.cid || !entry.record.byteLength)
|
|
169
|
+
return undefined;
|
|
170
|
+
if (!includeTakedowns && entry.takenDown)
|
|
171
|
+
return undefined;
|
|
172
|
+
let record;
|
|
173
|
+
try {
|
|
174
|
+
record = lexParseJsonBytes(entry.record, { strict: false });
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return undefined;
|
|
22
178
|
}
|
|
179
|
+
if (!isTypedLexMap(record))
|
|
180
|
+
return undefined;
|
|
181
|
+
return {
|
|
182
|
+
record,
|
|
183
|
+
cid: entry.cid,
|
|
184
|
+
sortedAt: parseDate(entry.sortedAt) ?? new Date(0),
|
|
185
|
+
indexedAt: parseDate(entry.indexedAt) ?? new Date(0),
|
|
186
|
+
takedownRef: safeTakedownRef(entry),
|
|
187
|
+
};
|
|
23
188
|
}
|
|
24
189
|
const emptySiteStandardRecords = () => ({
|
|
25
190
|
documents: new HydrationMap(),
|
|
26
191
|
publications: new HydrationMap(),
|
|
27
192
|
});
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
193
|
+
const siteStandardKind = (uri) => {
|
|
194
|
+
const parsed = parseAtUriString(uri);
|
|
195
|
+
if (!parsed.success)
|
|
196
|
+
return undefined;
|
|
197
|
+
switch (parsed.value.collection) {
|
|
198
|
+
case site.standard.document.$type:
|
|
199
|
+
return 'documents';
|
|
200
|
+
case site.standard.publication.$type:
|
|
201
|
+
return 'publications';
|
|
202
|
+
default:
|
|
203
|
+
return undefined;
|
|
35
204
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
205
|
+
};
|
|
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
|
+
/**
|
|
215
|
+
* Generic record bodies are unvalidated, so check them against the Lexicon
|
|
216
|
+
* before exposing typed fields. Parse mode is not used, to preserve the
|
|
217
|
+
* stored record as-is.
|
|
218
|
+
*/
|
|
219
|
+
const matchRecordInfo = (schema, info) => info && schema.$matches(info.record, { strict: false })
|
|
220
|
+
? { ...info, record: info.record }
|
|
221
|
+
: null;
|
|
222
|
+
/**
|
|
223
|
+
* Store a generic record in the map matching its collection. Records failing
|
|
224
|
+
* Lexicon validation are stored as null.
|
|
225
|
+
*/
|
|
226
|
+
const setSiteStandardRecord = (out, uri, key, info) => {
|
|
227
|
+
switch (siteStandardKind(uri)) {
|
|
228
|
+
case 'documents':
|
|
229
|
+
out.documents.set(key, matchRecordInfo(site.standard.document.main, info));
|
|
230
|
+
break;
|
|
231
|
+
case 'publications':
|
|
232
|
+
out.publications.set(key, matchRecordInfo(site.standard.publication.main, info));
|
|
233
|
+
break;
|
|
42
234
|
}
|
|
43
|
-
return { documents, publications };
|
|
44
235
|
};
|
|
45
236
|
/**
|
|
46
237
|
* Read-path resolution: caller pinned a set of `(uri, cid)` strongRefs in
|
|
@@ -77,7 +268,7 @@ export const getSiteStandardRecordsFromHydrationMapsByRefs = (associatedRefs, do
|
|
|
77
268
|
let document;
|
|
78
269
|
let publication;
|
|
79
270
|
for (const ref of associatedRefs) {
|
|
80
|
-
const key =
|
|
271
|
+
const key = genericRecordKey(ref.uri, ref.cid);
|
|
81
272
|
if (!document) {
|
|
82
273
|
const hit = documents?.get(key);
|
|
83
274
|
if (hit)
|
|
@@ -146,7 +337,7 @@ export const getSiteStandardRecordsFromHydrationMapsByDocumentUri = (documents,
|
|
|
146
337
|
for (const [key, info] of documents ?? []) {
|
|
147
338
|
if (!info)
|
|
148
339
|
continue;
|
|
149
|
-
document = { ref:
|
|
340
|
+
document = { ref: parseGenericRecordKey(key), info };
|
|
150
341
|
break;
|
|
151
342
|
}
|
|
152
343
|
let publication;
|
|
@@ -157,7 +348,7 @@ export const getSiteStandardRecordsFromHydrationMapsByDocumentUri = (documents,
|
|
|
157
348
|
for (const [key, info] of publications ?? []) {
|
|
158
349
|
if (!info)
|
|
159
350
|
continue;
|
|
160
|
-
const ref =
|
|
351
|
+
const ref = parseGenericRecordKey(key);
|
|
161
352
|
if (ref.uri === site) {
|
|
162
353
|
publication = { ref, info };
|
|
163
354
|
break;
|
|
@@ -175,7 +366,7 @@ export const getSiteStandardRecordsFromHydrationMapsByDocumentUri = (documents,
|
|
|
175
366
|
for (const [key, info] of publications ?? []) {
|
|
176
367
|
if (!info)
|
|
177
368
|
continue;
|
|
178
|
-
publication = { ref:
|
|
369
|
+
publication = { ref: parseGenericRecordKey(key), info };
|
|
179
370
|
break;
|
|
180
371
|
}
|
|
181
372
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external.js","sourceRoot":"","sources":["../../src/hydration/external.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AtUriString } from '@atproto/syntax'\nimport type { DataPlaneClient } from '../data-plane/client/index.js'\nimport { site } from '../lexicons/index.js'\nimport { hydrationLogger } from '../logger.js'\nimport type {\n GetSiteStandardRecordsByRefResponse,\n GetSiteStandardRecordsByURIResponse,\n} from '../proto/bsky_pb.js'\nimport {\n parseSiteStandardRecordKey,\n siteStandardRecordKey,\n} from '../util/standard-site.js'\nimport type {\n SiteStandardDocumentRecord,\n SiteStandardPublicationRecord,\n} from '../views/types.js'\nimport {\n HydrationMap,\n type ItemRef,\n type RecordInfo,\n parseRecord,\n} from './util.js'\n\nexport type SiteStandardDocument = RecordInfo<SiteStandardDocumentRecord>\nexport type SiteStandardPublication = RecordInfo<SiteStandardPublicationRecord>\n\n/**\n * Keyed by `${uri}@${cid}` — see `siteStandardRecordKey`. 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 async getSiteStandardRecordsByRef(\n refs: ItemRef[],\n includeTakedowns = false,\n ): Promise<SiteStandardRecords> {\n if (!refs.length) return emptySiteStandardRecords()\n\n const res = await this.dataplane.getSiteStandardRecordsByRef({\n refs: refs.map(({ uri, cid }) => ({ uri, cid: cid ?? '' })),\n })\n return buildSiteStandardRecordsHydrationMaps(res, includeTakedowns)\n }\n\n async getSiteStandardRecordsByURI(\n uris: AtUriString[],\n includeTakedowns = false,\n ): Promise<SiteStandardRecords> {\n if (!uris.length) return emptySiteStandardRecords()\n\n const res = await this.dataplane.getSiteStandardRecordsByURI({ uris })\n return buildSiteStandardRecordsHydrationMaps(res, includeTakedowns)\n }\n}\n\nconst emptySiteStandardRecords = (): SiteStandardRecords => ({\n documents: new HydrationMap(),\n publications: new HydrationMap(),\n})\n\nconst buildSiteStandardRecordsHydrationMaps = (\n res:\n GetSiteStandardRecordsByURIResponse | GetSiteStandardRecordsByRefResponse,\n includeTakedowns: boolean,\n): SiteStandardRecords => {\n const documents: SiteStandardDocuments = new HydrationMap()\n for (const { ref, record } of res.documents) {\n if (!ref?.uri || !ref.cid || !record) continue\n documents.set(\n siteStandardRecordKey(ref.uri, ref.cid),\n parseRecord(site.standard.document.main, record, includeTakedowns) ??\n null,\n )\n }\n const publications: SiteStandardPublications = new HydrationMap()\n for (const { ref, record } of res.publications) {\n if (!ref?.uri || !ref.cid || !record) continue\n publications.set(\n siteStandardRecordKey(ref.uri, ref.cid),\n parseRecord(site.standard.publication.main, record, includeTakedowns) ??\n null,\n )\n }\n return { documents, publications }\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 = siteStandardRecordKey(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: parseSiteStandardRecordKey(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 = parseSiteStandardRecordKey(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: parseSiteStandardRecordKey(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 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hydrator.d.ts","sourceRoot":"","sources":["../../src/hydration/hydrator.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,SAAS,EAEf,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAA;AACxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,KAAK,EACV,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,GAAG,EAAa,MAAM,sBAAsB,CAAA;AAErD,OAAO,KAAK,EAEV,YAAY,EACZ,YAAY,EAEb,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"hydrator.d.ts","sourceRoot":"","sources":["../../src/hydration/hydrator.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,SAAS,EAEf,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAA;AACxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,KAAK,EACV,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,GAAG,EAAa,MAAM,sBAAsB,CAAA;AAErD,OAAO,KAAK,EAEV,YAAY,EACZ,YAAY,EAEb,MAAM,qBAAqB,CAAA;AAI5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAQhD,OAAO,EACL,KAAK,0BAA0B,EAC/B,aAAa,EACb,KAAK,MAAM,EACX,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAEhB,KAAK,mBAAmB,EACzB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAE9B,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,QAAQ,EACb,YAAY,EACZ,KAAK,QAAQ,EACb,KAAK,wBAAwB,EAC7B,KAAK,KAAK,EACV,KAAK,IAAI,EACT,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,KAAK,EACV,KAAK,OAAO,EACZ,KAAK,cAAc,EAEnB,KAAK,WAAW,EACjB,MAAM,WAAW,CAAA;AAClB,OAAO,EAEL,KAAK,OAAO,EACZ,aAAa,EACb,KAAK,QAAQ,EACb,KAAK,SAAS,EAEd,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,KAAK,EAEV,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,QAAQ,EACb,MAAM,EACP,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,YAAY,EACZ,KAAK,OAAO,EACZ,KAAK,UAAU,EAOhB,MAAM,WAAW,CAAA;AAElB,qBAAa,UAAU;IAST,OAAO,CAAC,IAAI;IARxB,QAAQ,iBAAqB;IAC7B,MAAM,mCAAuE;IAC7E,gBAAgB,sBAA6B;IAC7C,gCAAgC,sBAA6C;IAC7E,eAAe,sBAA4B;IAC3C,gBAAgB,sBAA6B;IAC7C,iBAAiB,sBAA8B;IAC/C,QAAQ,2BAAqB;IAC7B,YAAoB,IAAI,EAAE,cAAc,EAAI;IAE5C,IAAI,kBAAkB,4CAGrB;IACD,IAAI,CAAC,CAAC,SAAS,OAAO,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,UAAU,GAAG,CAAC,CAEhE;CACF;AAED,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAElE,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,cAAc,CAAA;IACxB,MAAM,EAAE,SAAS,GAAG,IAAI,CAAA;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,gCAAgC,CAAC,EAAE,OAAO,CAAA;IAC1C,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,QAAQ,EAAE,wBAAwB,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;AAEpE,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,CAAC,EAAE,UAAU,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,mBAAmB,CAAA;IACpC,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,eAAe,CAAC,EAAE,oBAAoB,CAAA;IACtC,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,sBAAsB,CAAC,EAAE,sBAAsB,CAAA;IAC/C,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,cAAc,CAAC,EAAE,mBAAmB,CAAA;IACpC,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,cAAc,CAAC,EAAE,mBAAmB,CAAA;IACpC,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,cAAc,CAAC,EAAE,oBAAoB,CAAA;IACrC,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,qBAAqB,CAAC,EAAE,0BAA0B,CAAA;IAClD,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;IACzC,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C,wBAAwB,CAAC,EAAE,wBAAwB,CAAA;CACpD,CAAA;AAED,KAAK,yBAAyB,GAAG;IAC/B,WAAW,EAAE,WAAW,EAAE,CAAA;CAC3B,CAAA;AAED,KAAK,mBAAmB,GAAG,IAAI,CAC7B,wBAAwB,EACxB,2BAA2B,CAC5B,GAAG;IACF,WAAW,CAAC,EAAE,yBAAyB,CAAA;CACxC,CAAA;AAED,KAAK,uBAAuB,GAAG;IAC7B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAA;AAC1E,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;AAO7D,MAAM,MAAM,SAAS,GAAG,OAAO,CAAA;AAC/B,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;AAE7D,MAAM,MAAM,WAAW,GAAG,OAAO,CAAA;AACjC,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;AAEjE,MAAM,MAAM,mBAAmB,GAAG,YAAY,CAC5C,SAAS,EACT,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CACjC,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,GAAG,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,IAAI,CAAA;CACjB,CAAA;AAGD,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;AAE/E;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAClC,kBAAkB,EAAE,kBAAkB,CAAA;CACvC,CAAA;AAED,qBAAa,QAAQ;IAUV,SAAS,EAAE,eAAe;IATnC,KAAK,EAAE,aAAa,CAAA;IACpB,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,aAAa,CAAA;IACpB,KAAK,EAAE,aAAa,CAAA;IACpB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC5B,MAAM,EAAE,cAAc,CAAA;IAEtB,YACS,SAAS,EAAE,eAAe,EACjC,eAAe,EAAE,SAAS,SAAS,EAAE,YAAK,EAC1C,MAAM,EAAE,cAAc,EASvB;IAMK,qBAAqB,CACzB,IAAI,EAAE,SAAS,EAAE,EACjB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAqBzB;IAKK,eAAe,CACnB,IAAI,EAAE,SAAS,EAAE,EACjB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CA+CzB;IAMK,oBAAoB,CACxB,IAAI,EAAE,SAAS,EAAE,EACjB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAEzB;IAUK,uBAAuB,CAC3B,IAAI,EAAE,SAAS,EAAE,EACjB,GAAG,EAAE,UAAU,EACf,IAAI,CAAC,EAAE;QAEL,kBAAkB,CAAC,EAAE,SAAS,EAAE,CAAA;KACjC,GACA,OAAO,CAAC,cAAc,CAAC,CAuDzB;IAKK,YAAY,CAChB,IAAI,EAAE,WAAW,EAAE,EACnB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAQzB;IAIK,iBAAiB,CACrB,IAAI,EAAE,WAAW,EAAE,EACnB,GAAG,EAAE,UAAU,EACf,IAAI,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,GAC9B,OAAO,CAAC,cAAc,CAAC,CAsBzB;IAMK,gBAAgB,CACpB,IAAI,EAAE,WAAW,EAAE,EACnB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAUzB;IAEK,sBAAsB,CAC1B,IAAI,EAAE,WAAW,EAAE,EACnB,GAAG,EAAE,SAAS,EACd,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAiCzB;IAeK,YAAY,CAChB,IAAI,EAAE;QAAE,GAAG,EAAE,WAAW,CAAA;KAAE,EAAE,EAC5B,GAAG,EAAE,UAAU,EACf,KAAK,GAAE,cAAmB,EAC1B,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,cAAc,CAAC,CAgPzB;YAEa,iBAAiB;IAmFzB,gBAAgB,CACpB,KAAK,EAAE,QAAQ,EAAE,EACjB,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,cAAc,CAAC,CAmEzB;IAED;;;;;OAKG;IACG,gCAAgC,CACpC,IAAI,EAAE,WAAW,EAAE,EACnB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAyCzB;IAYK,kBAAkB,CACtB,IAAI,EAAE,OAAO,EAAE,EACf,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,IAAI,CAAC,mBAAmB,EAAE,aAAa,CAAM,GACrD,OAAO,CAAC,cAAc,CAAC,CA2BzB;YAEa,kBAAkB;IAwC1B,eAAe,CACnB,IAAI,EAAE,WAAW,EAAE,EAAE,kCAAkC;IACvD,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAwBzB;IAOK,wBAAwB,CAC5B,IAAI,EAAE,WAAW,EAAE,EACnB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAiBzB;IAcK,mBAAmB,CACvB,IAAI,EAAE,WAAW,EAAE,EACnB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CA2FzB;IAMK,YAAY,CAChB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,WAAW,EAAE,EACnB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAuBzB;IAMK,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE,UAAU,2BAMxD;IAMK,oBAAoB,CACxB,MAAM,EAAE,YAAY,EAAE,EACtB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CA6DzB;IAEK,2BAA2B,CAC/B,MAAM,EAAE,eAAe,EAAE,EACzB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAoFzB;IAEK,gBAAgB,CACpB,aAAa,EAAE,YAAY,EAAE,EAC7B,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CA4CzB;IAGK,cAAc,CAClB,IAAI,EAAE,WAAW,EAAE,EACnB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAqBzB;IAEK,0BAA0B,CAC9B,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,EAAE,eAAe;IACpD,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,mBAAmB,CAAC,CA8D9B;IAMK,eAAe,CACnB,IAAI,EAAE,SAAS,EAAE,EACjB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,cAAc,CAAC,CAiBzB;IAIK,SAAS,CAAC,GAAG,EAAE,WAAW,EAAE,gBAAgB,UAAQ,ijBA8GzD;IAEK,aAAa,CACjB,CAAC,SAAS,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,GAAG;QAC3C,QAAQ,CAAC,EAAE,wBAAwB,CAAA;KACpC,EACD,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,UAAU,GAAG;QAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAC,CA4BxD;IAEK,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAM1D;CACF;AA4KD,eAAO,MAAM,WAAW,WACd,cAAc,UACd,cAAc,KACrB,cAkEF,CAAA;AAED,eAAO,MAAM,eAAe,cAAe,cAAc,EAAE,mBAE1D,CAAA"}
|
|
@@ -6,11 +6,11 @@ import { NOTIFICATION_REASON } from '../api/app/bsky/notification/constants.js';
|
|
|
6
6
|
import { app, chat, com } from '../lexicons/index.js';
|
|
7
7
|
import { hydrationLogger } from '../logger.js';
|
|
8
8
|
import { events } from '../telemetry/events.js';
|
|
9
|
-
import { SITE_STANDARD_NSID_PREFIX
|
|
9
|
+
import { SITE_STANDARD_NSID_PREFIX } from '../util/standard-site.js';
|
|
10
10
|
import { uriToDid, uriToDid as didFromUri } from '../util/uris.js';
|
|
11
11
|
import { isExternalEmbedType, isListRuleType, isRecordEmbedType, isRecordWithMediaType, } from '../views/types.js';
|
|
12
12
|
import { ActorHydrator, } from './actor.js';
|
|
13
|
-
import { ExternalHydrator, } from './external.js';
|
|
13
|
+
import { ExternalHydrator, parseGenericRecordKey, } from './external.js';
|
|
14
14
|
import { FeedHydrator, } from './feed.js';
|
|
15
15
|
import { GraphHydrator, } from './graph.js';
|
|
16
16
|
import { LabelHydrator, Labels, } from './label.js';
|
|
@@ -409,7 +409,7 @@ export class Hydrator {
|
|
|
409
409
|
const knownProfileDidsSet = new Set(knownProfileDids);
|
|
410
410
|
const extraSsDids = [];
|
|
411
411
|
for (const key of siteStandardPublications.keys()) {
|
|
412
|
-
const did = uriToDid(
|
|
412
|
+
const did = uriToDid(parseGenericRecordKey(key).uri);
|
|
413
413
|
if (!knownProfileDidsSet.has(did)) {
|
|
414
414
|
knownProfileDidsSet.add(did);
|
|
415
415
|
extraSsDids.push(did);
|
|
@@ -584,7 +584,7 @@ export class Hydrator {
|
|
|
584
584
|
const knownDids = new Set(dids);
|
|
585
585
|
const extraDids = [];
|
|
586
586
|
for (const key of publications.keys()) {
|
|
587
|
-
const did = uriToDid(
|
|
587
|
+
const did = uriToDid(parseGenericRecordKey(key).uri);
|
|
588
588
|
if (!knownDids.has(did)) {
|
|
589
589
|
knownDids.add(did);
|
|
590
590
|
extraDids.push(did);
|
|
@@ -1424,7 +1424,7 @@ const actionSiteStandardTakedownLabels = (documents, publications, labels) => {
|
|
|
1424
1424
|
if (documents.size > 0 && publications.size > 0) {
|
|
1425
1425
|
const pubKeysByUri = new Map();
|
|
1426
1426
|
for (const key of publications.keys()) {
|
|
1427
|
-
const { uri } =
|
|
1427
|
+
const { uri } = parseGenericRecordKey(key);
|
|
1428
1428
|
const list = pubKeysByUri.get(uri);
|
|
1429
1429
|
if (list)
|
|
1430
1430
|
list.push(key);
|
|
@@ -1442,12 +1442,12 @@ const actionSiteStandardTakedownLabels = (documents, publications, labels) => {
|
|
|
1442
1442
|
}
|
|
1443
1443
|
// Per-record takedowns: null any entry whose subject URI is taken down.
|
|
1444
1444
|
for (const key of documents.keys()) {
|
|
1445
|
-
const { uri } =
|
|
1445
|
+
const { uri } = parseGenericRecordKey(key);
|
|
1446
1446
|
if (labels.get(uri)?.isTakendown)
|
|
1447
1447
|
documents.set(key, null);
|
|
1448
1448
|
}
|
|
1449
1449
|
for (const key of publications.keys()) {
|
|
1450
|
-
const { uri } =
|
|
1450
|
+
const { uri } = parseGenericRecordKey(key);
|
|
1451
1451
|
if (labels.get(uri)?.isTakendown)
|
|
1452
1452
|
publications.set(key, null);
|
|
1453
1453
|
}
|